我对monorepo的一些看法

250 阅读5分钟

前言

最近monorepo好像变得很火。总结我的职业生涯,也遇到过好些用了monorepo的项目。然而很多时候它给我带来的工作效率影响都是负面的。我明白这个方案在用对了场景的情况下有着很多好处,但事实上并不是所有的团队都需要它。如果你正在考虑使用monorepo,也许你会有收获。

monorepo的优势

能被如此多团队追捧,monorepo一定有它的原因。网络上讲monorepo功能、原理的文章有很多,这里就不过多的赘述了,我提的是monorepo的优势是什么?换句话说,当我们遇到什么问题时,才会想到要使用它?我总结monorepo的优势大致有下列这些:

  • 统一性: monorepo可以让我们用一个代码仓库管理所有项目,这样我们就可以很轻松地管理这些项目的版本,让他们直接关联性更高。
  • 简易的版本管理:仓库中的项目会引用默认的版本,不需要手动指定
  • 更便捷的部署流程:使用monorepo之后,可以把前后端的项目放在同一个代码仓库下构建部署CI/CD。
  • 代码复用性高:团队中的成员可以清晰看到别的项目的代码,并直接使用。不需要额外,把公共代码抽离,发布工具包
  • 更容易重构:由于所有代码都在一起,我们在重构时可以更加清晰看到项目之间的关系,不容易错漏
  • 更快的code review:统一的管理方式,可以让不同成员更容易做code review。不需要分别找各自的项目
  • 更好的测试体验:通常我们的整体项目需要多个子项目同时运行,采用monorepo的管理方式,可以让项目的启动变得更加便利。并且测试代码时,可以更好地追踪运行路线。
  • 降低团队适应代码的难度:统一的管理模式,可以让新团队成员加入后迅速对项目整体关系有了解,并掌握代码。

我遇到的monorepo

接下来我想讲讲我遇到过的某个monorepo。这是一个算比较重的项目,因为我们把所有的通用组件以及相关的配套工具拆成了一个个独立的package,每个都有自己的版本。当初这么做的目的是为了让所有的组件更项目主体配对,1.x.x版本的项目必须也用1.x.x版本的组件。因此我们的项目大致长这个样子:

.
├── package.josn
├── packages/
│   ├── packageA
│   ├── packageB
│   ├── packageC
│   ├── packageD
│   └── ...
└── ...

如上图所示,我们的文件基本都放在packages中,其中有项目的主类型,所以通用主机,相关服务以及通用工具等。借鉴VUE的仓库,我们也采用了yarn 的workspace加learn的管理方式。理论上来说,这个需求似乎跟方案是吻合的。但在实际操作时,缺有着诸多的不便。

组件的迭代过程繁琐

由于我们规定了每个大版本的模块之间必须是强耦合的,就是说1.X.X的项目,必须用1.X.X的组件,服务,工具等。然后每次发版都会单独打一个分支和tag。随着发版的次数越来越多,我们的分支数量也逐渐增加。从而导致一个问题的出现:组件的迭代变得极其困难。

举个例子,我们在2.x.x的某个组件中发现了bug,但我们的最新版本以及到了7.x.x。这时只能切换分支,修改BUG,重选发版迭代。但要注意的是,我们的3.x.x以及往后的版本的组件也是从2.x.x中继承过来的,这意味着,我们需要把3-7分支的组件也改一遍。整个过程变得极其繁琐,且容易出错。

原因:公共组件部分应该抽离

在这个项目中,我们采用monorepo为的是解决一个需求——项目版本的强管理。如果只是为了这个需求,monorepo看似是符合预期的。但我们犯了一个很严重的错误就是,错误的把公共资源统一管理。

在这里公共资源应该单独管理,为整体做解耦。而项目只要在每个大版本中用semver规范注目使用的对应的组件即可,这样当组件修复bug时,项目只要更新依赖就行。

monorepo并不是单纯的把项目用到的内容往一个仓库里放就行,反而比手动管理时,更需要开发者考虑它们之间的关联性。

尽管如此,我曾多次向上级反应这个情况,可是并没有接纳,导致代码越来越难维护。

总结

那么monorepo的核心究竟是什么?我认为从根本上,它是为解决大型项目在分仓库的情况下所引发的各种问题所诞生的。当项目只是刚开始或者在规划上规模就不是很大的时候,monorepo不应该是我们的首选。

此外,monorepo所管理的项目,应该是一个个独立的项目,同时他们之间又是强的版本耦合关系。最典型的就是前端,后端项目共有monorepo,再复杂一点的就是前端里可能会分web,客户端,小程序。后端里又分支付系统,物流系统等。当一些公共库,组件并不是这个项目专用的情况下,它们并不应该在monorepo的范围里。它们的存在反而会让项目的维护难度增加。

一旦作出了monorepo的管理选择,将会是一个团队的选择,因此应该再三考虑确认之后才决定。