在很长时间里,我对 monorepo 的理解一直很肤浅,我以为,把所有的代码都放在一个 CVS 的 Repo 里就叫 Monorepo 了。 好处是更容易分享代码,执行规范,合作部署,降低交流成本等等。 坏处无非是,CI 有更多的 overhead (需要用 Bazel 类的工具来智能构建),commit conflict 的可能性上升,非主流的组织结构等。

建立于在肤浅的理解之上,我每次一到有选择的时候我就会高呼 Monorepo。直到近日我忽然反思了一个问题:“我的理解的前提是什么?”,才发现了我自己潜意识里的定下前提可能会让我做出错误的决定。

原来我的肤浅的理解,一直建立的前提是:

  • 我站在的立场是 Tech Lead,并没有站在普通团队成员的立场上。
  • 我忽视了 Monorepo 成本和团队规模之间的关系。

作为团队核心成员,我自然而然希望项目全局尽收眼底,巴不得规范只用定义一次,巴不得大家都能一起分享知识。 然而,我仔细一想,普通群众其实往往用不着担心这些“优点”:规范制定,项目全局,传授知识(作为传授者)。 而更糟糕的是,Monorepo 的缺点却对普通成员影响更大,相比于传统的多 repo,学习难度被增加了,conflicts 增多了,这些都是切身痛点。 毕竟,遵循传统往往意味着更多的在线学习资源,更容易发挥自己,哪怕最后是让组织作为一个整体来给增加的成本买单。

可见,从这个角度上看,用顶层视角来介绍 Monorepo 给团队成员很可能不受欢迎,即使实施了可能也不会有好果子。 因此,要想说服团队成员 Monorepo 的好处,更多的是要提升队员的水平,争取不要有“次元壁”,好让队员能够更深入理解,而非停留于表面。


当然,提升队员的水平不总是现实的,有时候决策人总得帮别人做决定,这时就只好自知冷暖,争取做一个到最后大家都开心的决定。如何做正确的决定? 这就回到了上面我说的第二个点,不能忽视成本和“团队规模”的关系。

现今网上的素材那么多,若是想说套话来支持自己的观点,就把我文首的那些简单的观点用一些繁琐的方式说出来就完事了。但如果你在乎成本,就要考虑他们是不是准确的。

实际上,随着团队规模到达一个程度,不论是工程团队的管理协作难点往往会超越技术的范畴。 不管我们怎么组织代码,只要代码多到一定程度,不论是哪个团队成员,都不可能了解全部代码,甚至可能出现代码量多到一个人的电脑无法承载的程度。 这个时候,Monorepo 的讨论就应该加入“我们要花多少成本在改善 CVS 上”这个问题。因此,“更容易分享代码”在大团队里,应该是个大问号。

问题还非但停留于 CVS 上,主流的开发工具往往是为了单项目开发的,monorepo 增加的复杂度很可能会打破既有工作流程。 譬如说 tsserver 的编辑器整合,在规模中小的情况下,所有代码都可以被加载。 稍微有一点规模之后,就会面临性能问题。如果退而求其次,让每个团队成员专注于在某个子文件夹下工作,确实是暂时规避了编辑器和 tsserver 的性能问题,但是如果想做跨项目的开发,就一下成了麻烦事。

跳出了开发的环节,部署环节呢?实际上,在大型组织里,部署环节和代码组织结构是个风马牛不想干的事。 比如,假如每个功能都有 feature flag,很多所谓的“原子部署”的优势也就无所谓了。 何况,部署环节更重要的问题往往是在怎么做 blue/green deployment,canary analysis 之类的,代码在哪,产物在哪,实际上无所谓。

说了那么多,我莫非是在说当人一多了,monorepo 就不香了吗? 不是的。 我的观点还是如果有足够的工程实力,应该争取使用 monorepo,因为 monorepo 相比于传统的做法代表了更多的可能性。 但是作为决策人,应该很清楚的意识到 monorepo 与否,是个在特定场合下针对特定人有意义的问题,天时地利人和一过(组织过大,团队水平有限等等),最好还是转移战场思考别的问题。


所谓 “Pick your battle. 🙂”