Skip to main content

什么是Monorepo?

什么是 Monorepo?

Monorepo 是管理项目的一种方式,即将所有的代码都放在一个仓库中,而不是像传统的方式一样,将每个项目放在单独的仓库中。 这种方式的好处是:

  • 代码复用,不同项目之间可以共享代码
  • CI/CD 的复用,不同项目之间可以共享 CI/CD 的配置
  • 管理方便,能够清楚直观的看到所有项目的代码以及版本
  • 依赖管理,不同项目之间可以共享依赖

集合这些优势,Monorepo 的使用越来越广泛,其中比较知名的 Monorepo 使用者就有 Google。 据说,Google 的代码库有数十亿行代码,数百万个文件,数千个开发者,数千个项目,但是所有的代码都在一个仓库中。

Monorepo 的缺点

  • 代码量大,拉取代码的时间会比较长
  • 代码量大,编译时间会比较长
  • 代码量大,IDE 的性能会受到影响
  • 代码包多,需要额外的工具来管理代码包

最常见的问题就是,如果一个 Monorepo 的包进行了修改,在 CI 发布的时候, 所有的包都需要重新发布,这样会导致发布时间变长。但是优势也是很明显的,当一个包进行了修改的时候, 其他所有依赖这个包的项目都会自动更新,不需要手动更新。

Monorepo 的工具

Lerna

Lerna 是一个管理 Monorepo 的工具,它可以帮助我们管理 Monorepo 中的包,以及管理包之间的依赖关系。 在项目中,如果我们有 A 包和 B 包,A 包依赖于 B 包,那么我们可以通过 Lerna 来管理这两个包。 当我们修改了 B 包的代码之后,Lerna 会自动帮我们将 A 包中依赖 B 包的代码更新到最新版本,而我们只需要在 A 包中定义 B 的版本为workspace:*即可。 在打包的时候,Lerna 会帮忙把 B 包的版本自动替换到最新的版本去。譬如,B 包此时的版本是1.0.0, 那么打包的时候,Lerna 会自动将 B 包的workspace:*版本替换成1.0.1

Turbo Repo

Turbo repo 是一个相对较新的 Monorepo 管理工具,由 Vercel 开发。它并不具备 Lerna 的发包功能,就是 它不能自动更新发包时的版本号,但是它有一个很大的优势,就是它可以自动的将 Monorepo 中的包 Cache。 只会对修改的包进行重新打包,而不会对所有的包进行重新打包。这样就大大的提高了打包的速度。 并且 Turbo repo 还支持 Remote Cache,可以将打包好的包缓存到远程服务器上,这样就可以在不同的机器上共享缓存了。 这种共享甚至不局限于 CI 环境,团队里的每个人都可以共享这个缓存,这样就可以大大的提高打包的速度。

总结

Monorepo 的优势是显而易见的,但是它的缺点也是很明显的,那就是代码量大,打包时间长,IDE 性能差。 但是随着工具的发展,这些问题都可以得到解决,譬如 Turbo repo 就可以解决打包时间长的问题。 我们的@meta-metopia/packages便是用到了 Lerna 和 Turbo repo 两个工具来进行管理的。

其中 Lerna 是用来发布版本的,而 Turbo repo 是用来打包的。具体的详细细节,我会在接下里的章节中讲到。