monorepo介绍与实践🥂

5,614 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 13 天,点击查看活动详情

1、前言

近年来,随着项目代码的累积,项目的代码组织管理问题日益突出。

monorepo因其在特定场景的优势收到了广泛关注。谷歌、微软、优步等公司纷纷落地monorepo。前端领域,React、Vue、Babel等项目也积极拥抱monorepo。

本文主要从monorepo的概念、monorepo与multirepo的比较、monorepo的实践这几个方面来介绍monorepo及其在前端领域的应用,以期为代码库管理提供借鉴。

monorepo 是什么?

一个产品会有多个项目,每个项目之间会存在版本同步的问题,如何在其中一个项目发布上线后,保证每个项目版本升级后的版本同步问题,提出的解决方案就是 monorepo 策略。

monorepo 是一种将多个项目代码存储在一个仓库里的软件开发策略(mono 意为单一,repo 意为 仓库)。与之相对的是另一种流行的代码管理方式 MultiRepo,即每个项目对应一个单独的仓库来分散管理。

image.png

2、monorepo与multirepo

目前主流的repo管理模式为monorepo与multirepo。

monorepo是一种用一个仓库管理应用代码的代码组织模式。

multirepo是一种用独立仓库管理应用代码的代码组织模式。

monorepo不是简单的将不同应用的代码放到一个仓库的不同文件夹中。Vue 3源码的monorepo结构图所示。

下面将从团队规模、工程配置、依赖管理、开发体验、Git管理与CI/CD等几个方面来对monorepo与multirepo的优势与劣势进行比较分析。

  • 团队规模

monorepo:小团队易上手,

multirepo:多团队,权限管理(不是所有人都可以有所有代码库的权限)

  • 工程配置

monorepo:工程统一标准(git hooks、eslint、prettier、tsconfig、babel)

multirepo:各有一套标准

  • 依赖管理

monorepo:可以提取公共依赖,版本控制容易,Phantom dependencies(幻影依赖、幽灵依赖、隐式依赖)存在,工作流配置一次

multirepo:依赖重复安装,依赖版本不一,配置多个工作流

  • 开发

monorepo:在一个仓库,编码方便,调试方便,可复用,项目庞大,拉取、安装依赖、构建耗时,

multirepo:代码体积小,模块划分清晰,多仓库切换,不利于代码复用

  • Git管理

monrepo:一个仓库,

multirepo:权限分配

  • CI/CD

monrepo:依靠工具链可以快速实现,发布慢(全量安装依赖,全量构建)

multirepo:重复下载依赖(单独安装,单独构建)

3、monorepo工具

这部分主要是介绍monorepo工具及在前端领域落地的方案。相关落地方案如下:

  1. Lerna(lerna.js.org/

Lerna是一个用于管理多个应用源代码的管理工具。babel、create-react-app、vue-cli等优秀前端项目都应用了Lerna。lerna import可以保存所有commit信息。

  1. Yarn Workspace(classic.yarnpkg.com/en/docs/wor…

Workspace 能更好的统一管理有多个项目的仓库,既可在每个项目下使用独立的 package.json 管理依赖,又可便利的享受一条 yarn 命令安装或者升级所有依赖等。更重要的是可以使多个项目共享同一个 node_modules 目录,提升开发效率和降低磁盘空间占用。vue、react、jest等项目用到了Yarn Workspace。

  1. Bit(bit.dev/

Bit是一个开源工具链,用于从独立的组件组成现代应用程序。在Bit中构建的是组件而不是应用。

  1. Nx(nx.dev/

Nx是一个智能的、可扩展的构建框架,对许多前端和后端技术都有一流的支持。

  1. Rush(rushjs.io/

Rush是由微软出品的一个专门为monorepo打造的项目管理工具。Rush解决了两个重要的问题:phantom dependencies 和 doppelgangers。

  1. Bazel(bazel.build/

Bazel是由Google开发。Bazel是一个用于大型应用程序的构建工具,它可以处理多语言依赖关系,并支持许多现代语言(Java、JS、Go、c++等)。Bazel可以用来构建与测试Angular项目。

  1. Buck(buck.build/

Buck是一个由Facebook开发和使用的构建系统。它鼓励创建由代码和资源组成的小型可重用模块,并支持多种平台上的各种语言。

  1. Pants(www.pantsbuild.org/

Pants是一个由Twitter推出的monorepo构建系统,其目标是成为一个快速、可扩展的构建系统,以适应不断增长的代码库。Pants主要用于Python项目。

  1. Please(please.build/index.html

Please是一个强调高性能、可扩展性和正确性的跨语言构建系统。

  1. Oao(github.com/guigrpa/oao

Oao是一个基于Yarn的monorepo管理工具。Oao在bootstrap以及依赖的添加/升级/删除方面做了优化。

  1. Bolt Pkg(github.com/boltpkg/bol…

Bolt是一个超级强大的JavaScript项目管理工具。

  1. pnpm(pnpm.io/zh/

pnpm快速的,节省磁盘空间的包管理工具,内置支持了单仓多包。

  1. Layer-pack(github.com/layer-pack/…

Layer-pack是一个用于glob导入,单仓多包,依赖继承的Webpack插件。

通过对这些monorepo工具的梳理,发现monorepo工具也不是银弹,有不同的定位,因而monorepo工具的开发有一种相互借鉴的趋势。

4、总结

monorepo不是一个新概念,也不是一个旧瓶装新酒的噱头,而是特定场景下代码组织模式的一种选择。monorepo与multirepo因其在特定场景的优势受到了不同程度的关注。软件开发没有银弹,monorepo也不是银弹。monorepo只有在不同项目发展到不同阶段才值得落地,才能发挥应有的价值。另外,monorepo与multirepo的抉择也是微前端架构演进过程中的必经之路。DDD(Domain-Driven Design)或许可以为monorepo与multirepo的抉择提供一个视角。项目是否适合应用monorepo,应用哪种monorepo工具是一个需要持续探索的问题。

参考文献

  1. juejin.cn/post/694487…
  2. juejin.cn/post/697030…
  3. juejin.cn/post/695008…
  4. segmentfault.com/a/119000003…
  5. segmentfault.com/a/119000003…
  6. blog.thundra.io/mono-or-mul…
  7. ***mp.weixin.qq.com/s/PIdmJ2cHm…
  8. segmentfault.com/a/119000002…
  9. people.engr.ncsu.edu/ermurph3/pa…
  10. dl.acm.org/doi/pdf/10.…(一篇介绍 Google 如何将数十亿代码通过 monorepo 方式组织的论文)
  11. github.com/korfuri/awe…(介绍实践 monorepo 生态)
  12. mp.weixin.qq.com/s/qQIFD7boA…(Monorepo 进化论 - monorepo 内 Node 部署)
  13. medium.com/@mattklein1…
  14. duapp.yuque.com/team_tech/b…
  15. mp.weixin.qq.com/s/3h86y4oBX…
  16. www.angulararchitects.io/aktuelles/t…

有bug?想补充?

感谢大家观看这篇文章,有任何问题或想和我交流,请直接留言,

发现文章有不妥之处,也可指出交流,感谢阅读~

53875b26-8251-4ccc-ad02-70badf65d662.gif