『』Monorepo可能没你想象中那么香……


全文共2500字 , 预计学习时长10分钟

『』Monorepo可能没你想象中那么香……
本文插图

图源:slideshare
最近许多流行的开源项目都存在这样的现象 , 就是在一个存储库中包含多个npm微包 , React、Parcel、Babel等等皆是如此 。
然而Monorepo可能没你想象中那么香 , 笔者认为 , 在大多数情况下 , 这种模式对项目是弊大于利的 , 它引入了不必要的复杂性 , 牺牲了作者和开发人员的可用性 。

『』Monorepo可能没你想象中那么香……
本文插图

为什么选择Monorepos?
monorepos的概念是简化依赖项管理 。 如果项目包含许多包 , 这些包需要依赖于彼此的特定版本 , 那么将它们放在一个地方而不是放在单独的存储库中就可以更容易地管理 。
同样 , 对于一个历史记录 , 这些包将始终具有同步或“原子”提交 。 为了让事情变得更简单 , 可以使用自定义脚本自动管理所有包的发布 , 这样一来 , 没有相应的包 , 这个包就不会发布 。
一个JavaScriptmonorepo项目通常会有这样的结构:
myproject.git/ packages/ package-1/ package.json package-2/ package.json package-3/ package.json ... scripts/ common-publishing-script.js
这只是一个小例子 , 你可以看到monorepos可以得到多大的值:
· React: 32个包
(https://github.com/facebook/react/tree/master/packages)
· Parcel: 81个包
(https://github.com/parcel-bundler/parcel/tree/v2/packages)
· Babel: 138个包
(https://github.com/babel/babel/tree/master/packages)
这很荒谬 , 下面笔者将解释为什么要反对monorepos概念 , 以及为什么这是一种反模式 。

『』Monorepo可能没你想象中那么香……
本文插图

掩盖monolith
将代码分解成多个包有几个好处 , 无论是库、微服务还是微前端 , 都显著地提高了构建速度 , 可以进行独立部署 , 并在多个团队之间并行化开发 , 所有这些都通过一个大家可以依赖的约定API进行集成 。
但是 , 如果所有这些都托管在同一个存储库中 , 很多好处就不复存在了 。

『』Monorepo可能没你想象中那么香……
本文插图

图源:unsplash
虽然最初看起来monorepos并没有与monolith相同的问题 , 并且还可以单独维护包 , 但是当进一步检查这些存储库时 , monolith变得非常明显 。 通常有一个复杂的依赖关系树 , 其中所有的包都倾向于相互依赖才能发挥功能 。
如果对其中一个包进行更改 , 可能会对使用该包的包产生连锁反应 , 而这些包本身必须更新和发布 。 通常在monorepos中 , 包的功能是非常特殊的 , 那么问题就变成了如果它是紧密耦合的 , 为什么还要有一个单独的包呢?可以独立使用这些包吗?或者与monorepo中其他包的特定版本绑定?它可能更容易卸下伪装 , 就和momolith一样 。

『』Monorepo可能没你想象中那么香……
本文插图

只有一个包使用了Parcel包 , 就是它本身 。

『』Monorepo可能没你想象中那么香……
本文插图

包的开销
当查看node_modules目录时 , 即使对于一个相对基本的应用程序 , 也可能有数百甚至数千个包 。 通常这样的包只包含几行代码 , 并附带LICENCE、README和package.json文件 。
这是一笔令人难以置信的开销和浪费 。 包会消耗更多的硬盘空间 , 增加安装时间 , 并且在功能上变得更加模糊 , 以至于有些名称就直接描述了它们的功能 。


推荐阅读