Hello Monorepo(上)

简介: Hello Monorepo(上)

为了解决代码共享、重复和一致性等问题,越来越多的开发团队转向了Monorepo。本文就来了解一下什么是 Monorepo,它们可以带来哪些好处,以及常用的 Monorepo 开发工具。帮助我们更好地理解和应用这一代码管理策略。让我们一起进入Monorepo的世界,打破传统的代码管理方式,迎接更高效的软件开发体验!


什么是 Monorepo ?


Monorepo 是一个包含多个独立项目,并且具有明确定义的关系的单个代码库。1.webp.jpg一个真正的Monorepo不仅仅是将多个项目的代码放在同一个代码库中。它还需要这些项目之间有明确定义的关系。如果这些项目之间没有良好定义的关系,那么就不能称之为Monorepo。

类似地,如果一个代码库中包含了一个庞大的应用,而没有对其进行分割和封装,那么这只是一个大型的代码库,而不是真正的Monorepo。即使你给它取一个花里胡哨的名字,也不能改变它的本质。

事实上,一个优秀的Monorepo正好与庞大的代码库相反,它应该具有良好的结构和模块化。2.webp.jpg


Monorepo 解决了什么问题?


Polyrepo

为了讨论的方便,假设多个代码库("polyrepo")是与单一代码库("monorepo")相对应的概念。polyrepo 表示多代码库,是当前开发应用的标准方式:每个团队、应用或项目都有一个代码库。通常情况下,每个代码库只有一个构建产物,并且拥有简单的构建流程。3.webp.jpg行业之所以采用多代码库的方式进行开发,有一个重要原因:团队自治。团队希望能够自主决定使用哪些库,何时部署应用或库,以及谁可以贡献或使用他们的代码。

团队自治是一种组织架构和开发模式的趋势,它赋予了团队更大的自主权和灵活性。每个团队拥有自己的代码库,可以根据自己的需求和优先级进行独立的决策和开发。这种方式能够提高团队的效率和创造力,同时也减少了团队之间的依赖和冲突。4.webp.jpg这些都是好的方面,那么为什么需要采取不同的方式呢?因为这种自治是通过隔离来实现的,而隔离却会损害协作。具体来说,在多代码库环境中存在以下常见问题:

  • 繁琐的代码共享:要在多个代码库之间共享代码,可能需要为共享代码创建一个专门的代码库。这样就需要设置工具和持续集成(CI)环境,将贡献者添加到代码库中,并设置包发布,以便其他代码库可以依赖它。更不用说在多个代码库之间解决不兼容的第三方库版本的问题了…
  • 大量代码重复:由于不愿意费事设置共享的代码库,团队通常会在每个代码库中编写自己的常见服务和组件的实现,这导致了很多代码重复。这种做法不仅浪费了时间,而且在组件和服务发生变化时增加了维护、安全性和质量控制的负担。
  • 对共享库和消费者进行成本高昂的跨存储库更改:在多个代码库中进行共享库的跨库更改是具有挑战性且成本较高的。当一个共享库需要进行关键 bug 修复或重大变更时,开发人员需要在各个代码库中逐一应用这些修改,而这些代码库之间可能存在孤立的修订历史。这也意味着必须在每个代码库中进行相应的测试和验证,确保更改不会引入新的问题。
  • 工具不一致:工具链的不一致性会给开发人员带来额外的负担。不同的项目使用不同的命令和工具,可能需要花费时间和精力来适应和记忆这些差异。而且,当需要在多个项目之间进行切换时,频繁地切换命令和工具可能会导致混淆和错误。

Monorepo

在多代码库环境("polyrepo")中工作时,可能会遇到一些问题。 那单一代码库("monorepo")是如何解决这些问题的呢?

  • 创建新项目无需额外开销:创建新项目无需额外的开销。如果所有消费者都在同一个代码库中,可以直接在现有的开发环境中创建和设置新项目,避免了额外的资源和配置成本。
  • 原子提交跨项目:每次提交都能确保所有项目能够协同工作。当在同一次提交中修复所有问题时,不存在破坏性变更的问题,因为所有修改都是一起完成的。
  • 同一版本的所有内容:可以避免因项目依赖冲突而导致的不兼容性问题。所有项目都共享同一份代码库,使用相同的第三方库版本,减少了版本管理和冲突解决的复杂性。
  • 开发灵活性:可以建立一种统一的构建和测试应用程序的方式,即使这些应用程序使用不同的工具和技术。开发人员可以自信地为其他团队的应用程序做出贡献,并验证其更改是安全的。


Monorepo 工具有哪些?


Monorepo 拥有许多优势,但为了使其发挥作用,需要使用正确的工具。随着工作空间的扩大,这些工具必须帮助开发者保持高效、可理解和可管理。

那 Monorepo 工具应该提供些什么呢?

  • 本地计算缓存
  • 本地任务编排
  • 分布式计算缓存
  • 分布式任务执行
  • 透明远程执行
  • 检测受影响的项目/包
  • 工作区分析
  • 依赖图可视化
  • 代码共享
  • 一致的工具
  • 代码生成
  • 项目约束和可见性

注意:除了功能以外,还有其他因素会影响使用体验。尽管一个工具可能在某些方面功能不如其他工具强大,但由于用户体验、成熟度、文档、编辑器支持等因素的差异,用户可能会更喜欢使用它。有些功能可以很容易地通过自定义实现来添加,而有些功能则无法通过简单的修改来实现。因此,除了关注功能外,还需要综合考虑其他因素来选择适合自己需求的工具。

比较流行的 Monorepo 工具如下:

工具 开发团队 简介
Bazel 谷歌 快速、可扩展、多语言且可扩展的构建系统。
Gradle Build Tool Gradle 专为多项目构建而设计的快速、灵活的多语言构建系统。
Lage 微软 JS monorepos 中的任务运行器。
Lerna Nrwl 一个用于管理具有多个包的 JavaScript 项目的工具。
Nx Nrwl 下一代构建系统具有一流的 monorepo 支持和强大的集成。
Pants Pants Build 一个快速、可扩展、用户友好的构建系统,适用于各种规模的代码库。
Rush 微软 适合拥有大量团队和项目的大型单一仓库。属于 Rush Stack 项目系列的一部分。
Turborepo Vercel JavaScript 和 TypeScript 代码库的高性能构建系统

接下来将逐个功能来比较各个 Monorepo 工具在这些功能上的表现。

本地计算缓存

本地计算缓存是指在进行任务执行时,将任务的输入、输出和中间结果存储在本地机器上,以便在后续的构建或测试过程中可以直接使用这些已经计算过的结果,而不需要重新执行相同的任务。5.webp.jpg

工具 是否支持
Bazel
Gradle Build Tool ✅ Gradle Build Tool 本身提供本地构建缓存。Gradle Enterprise 添加了对复制和管理的支持。
Lage
Lerna ✅ Lerna v6 具有由 Nx 提供支持的内置本地计算缓存。
Nx
Pants ✅ 像React一样,Nx在从其缓存中恢复结果时进行了树差异比较,这使得它在平均情况下比其他工具更快
Rush ✅ 利用系统 tar 命令更快地恢复文件。
Turborepo

本地任务编排

本地任务编排是指在执行任务时,按照规定的顺序和并行方式来管理和执行这些任务。任务之间可能存在依赖关系,需要按照正确的顺序进行执行,同时还可以利用并行计算的优势,提高任务的执行效率。6.webp.jpg

工具 是否支持
Bazel
Gradle Build Tool ✅ Gradle Build Tool 通过配置提供对并行任务的支持,并通过其灵活的 Groovy 或 Kotlin DSL 提供任务编排支持。
Lage
Lerna ✅ Lerna v6 充分利用了 Nx 来高效地协调和并行执行任务。
Nx
Pants
Rush ✅ 支持此功能。命令可以被建模为简单的脚本,也可以作为独立的“阶段”(例如构建、测试等)。
Turborepo

分布式计算缓存

分布式计算缓存允许在不同的环境中共享缓存结果。通过共享缓存,整个组织中的不同部门或团队可以共享已经计算过的结果,避免重复构建或测试相同的内容。7.webp.jpg

工具 是否支持
Bazel
Gradle Build Tool ✅ Gradle Build Tool 提供远程分布式缓存。 Gradle Enterprise 添加了对复制和管理的支持。
Lage
Lerna ✅ Lerna v6 可以连接到 Nx Cloud 以启用分布式缓存。
Nx
Pants
Rush ✅ Rush 内置了对 Azure 和 AWS 存储的支持,并具有允许自定义缓存提供程序的插件 API。
Turborepo


Hello Monorepo(下)https://developer.aliyun.com/article/1411558

相关文章
|
7月前
|
数据可视化 JavaScript 前端开发
Hello Monorepo(下)
Hello Monorepo(下)
105 0
|
存储 JSON 资源调度
10分钟带你从0到1搭建monorepo 工程化项目(一)
前言 大家好,我是Fly哥, 之前写博客的仓库,还是用的原生的html 和js 也没有引入 ts , 和一些工程化的东西, 所以自己重新搭建了一套前端项目架构 基于 lerna + yarn 的 monrepo的仓库, 主要是后面会学习输出的一些东西, 整个架子先搭建起来。 2d 和 3d 公共 util 的封装 个人 npm 包的发布 (rollup) 2d react 项目 搭建(vite) 3d react 项目 搭建 (webpack) 搭建一套基于webpack 5 的cli 每个项目都有一些特定的依赖, 但是也会有一些相同的依赖。比如eslint、 babel 的一些基础配置,
10分钟带你从0到1搭建monorepo 工程化项目(一)
|
4月前
|
JavaScript 前端开发
什么是前端构建工具?vite和vite脚手架的关系!
【8月更文挑战第1天】前端构建工具简析
88 4
|
5月前
|
前端开发 JavaScript 开发工具
使用RequireJS和Bower优化前端资源管理和模块化开发
【7月更文挑战第7天】随着Web应用的复杂度日益增长,前端资源管理和模块化开发变得尤为重要。RequireJS和Bower是两个流行的前端开发工具,它们分别解决了JavaScript模块化加载和前端包依赖管理的问题,极大地提升了开发效率和代码质量。
91 3
|
6月前
|
资源调度 前端开发 JavaScript
前端工程化实践:Monorepo与Lerna管理
**前端工程化中,Monorepo和Lerna用于大型项目管理。Monorepo集纳所有项目,便于代码共享、版本控制和CI/CD。Lerna是Monorepo工具,管理多npm包,支持独立或共享版本。安装Lerna用`npm install --save-dev lerna`,初始化后可创建、管理包,通过`lerna bootstrap`、`lerna add`、`lerna publish`等命令协同工作。Lerna配置可在`lerna.json`,与CI/CD工具集成实现自动化。
79 0
|
7月前
|
JSON JavaScript 数据格式
使用pnpm搭建monorepo开发环境
使用pnpm搭建monorepo开发环境
330 0
|
缓存 前端开发 JavaScript
前端工具Vite的出现解决了什么?
在 ESM 出现之前,Javascript 是没有一个标准的模块方案。 比如说 `CJS` 是用于 Node 服务端的模块化方案,`AMD` 是用于浏览器的模块化方案。为了解决这个模块共用性问题,出现了 `UMD` 用于兼容这两种模块规范。 鉴于上面共用性问题,实际开发中配置的打包方式,采用的还是 UMD 模式。因为这样可以避免打包而产生的规范问题,并且在 ESM 不能使用的情况下也会选择 UMD。
141 0
前端工具Vite的出现解决了什么?
|
存储 资源调度 安全
pnpm:基础使用
pnpm:基础使用
448 0
|
Web App开发 存储 缓存
前端MonoRepo实战:pnpm+nx搭建MonoRepo项目
之前大多数是理论知识,能让我们知道pnpm 和nx 是什么,但是具体要到项目实战就有点懵,不知道从而下手,下面我们就一步步开始搭建pnpm+nx的Monorepo仓库。
1584 0
|
缓存 分布式计算 前端开发
从npm版本依赖到Monorepo大仓项目
前端的发展很快,自从node.js的出现,打开前端新的大门,npm让js有了自己的包管理能力,能够让前端项目工程化,从而能够处理更加复杂的前端项目。
286 0