About Monorepo

什么是 monorepo (opens in a new tab)

Monorepo 的背后是什么?仓库/代码组织方式

单个仓库应该以怎样的方式组织,是单仓单应用(Polyrepo)还是单仓多应用(Monorepo),或者是两种都要支持?

只支持 monorepo 并且 monorepo 里的多个应用应该具备很强的关联性,避免职责不清晰的过大的 monorepo

概念说明:

  • monorepo:单仓库多应用/多包
  • polyrepo:单仓库单应用/单包,也叫 multi-repo

https://github.com/joelparkerhenderson/monorepo-vs-polyrepo (opens in a new tab)

核心观点:

  • Monorepo 里的子应用们应该有很强的关联性,在这种场景下才能发挥出 monorepo 的优势,不要把关联性不大的应用放在一个 monorepo 里,没有收益,并且会带来管理复杂度
  • 大部分业务之间的应用是比较独立的,关联性不大,不要把某个业务线的应用都放在一个 monorepo 里,比如直播的所有应用、或者直播营收线的所有应用

monorepo 的收益?

  • 减少不同业务仓库的差异性,减少跨仓库开发心智
  • 减少 universal infrastructure 核心链路上的分叉,降低开发者使用成本,和 Ufra 的复杂度,便于统一维护,提高效率
    • 可以展开来讲

一个 monorepo 应该负责多大的范围以及应该包含多少个应用?

从业务开发者的视角来看,monorepo 相比于 polyrepo 复杂度一定是更高一些的,而且随着 monorepo 里的应用变多这个复杂度会持续提升,因此我们并不推荐过大的 monorepo,具体的原因:

  • 业务迭代敏捷度降低,对于新人或者架构团队排查问题尤其不友好,在安装依赖的过程中会遇到很多奇奇怪怪的问题,对开发者要求较高
  • 仓库体积不受控的持续变大,分支、commit、MR 越来越多,非常不利于管理
  • 业务交接成本变高,比如仓库中的某个应用要交接到其他团队,要么花费很高的成本把应用代码迁移出去,要么让其他业务的开发者进到这个仓库开发
  • 同一仓库的协作者过多,代码权限不可控,比如某个业务的外包、比如被交接团队的开发者,都默认拥有了整个仓库所有应用的代码权限
  • 单个业务/应用的灵活性降低,某个业务想要在工程上有一些定制性、想要升级某个基础依赖、想要有差异化的能力,这些可能都要依赖到整个仓库的改动

一个 monorepo 应该负责多大的业务范围? 一个 monorepo 里的应用们应该是有很强的关联性,比如业务功能上的强相关、有很多可复用的代码、一次迭代经常要跨这几个应用。

Monorepo 的大小或者包含的应用个数其实并不是关键,关键还是这些应用的关联性是不是足够强。关联性强的应用放到一个仓库里可以大大提高我们的研发效率,而关联性不强的应用放在一起则对我们的效率有负向,并且长期可能会产生质量问题。

在这个问题上,技术产品和业务是有极大区别的:

对于一个定位清晰的技术产品,可能会包含很多 NPM 包,这些包都有极强的关联性,因此放在一个仓库里是可以极大降低管理成本的,以 Babel 为例,看起来仓库里有 100 多个 NPM 包,但这些包很主包 babel 的关联性都是非常大的,并且这些包本质都是在几个分类下的,所以看起来是个大的 monorepo,但整体结构是很清晰的。

对于业务来说,每个业务应用的独立性是很强的,大部分业务应用之间都没太多耦合,比如直播里的福袋和红包从研发侧毫无关系、比如直播个人中心与神秘商店也就是有个入口而已,因此从这个视角看把这些应用放到一个仓库里显然是没有必要的。

links

What is a monorepo (opens in a new tab)

比较详细的 monorepo 介绍 & 现有业界工具横向对比