代码管理一直是一个棘手的问题,好在很多人在关注。
本文部分内容是翻译:Monorepo Explained
什么是 Monorepo ?
Monorepo
是一个包含多个具有关联性项目的单一存储库。
如果一个存储库中管理了多个项目,而这些项目没有任何关联,我们并不能称其为 Monorepo
,它只能算是一个巨石仓库(庞大的仓库)。
为什么使用 Monorepo ?
为了讨论这个问题,我们假设 Polyrepo
(非单一存储库) 是 Monorepo
的反例。
vs. 多仓库 ( Multirepo、Polyrepo )
Polyrepo
是目前开发应用的普遍方式:一个存储库对应一个团队、应用或项目。通常,每个存储库都能构建出一个产物,它们拥有自己的构建管道。
使用 Polyrepo
有一个很大的原因 —— 团队自治。每个团队可以自主决定使用什么库、什么时候发布应用或库,也可以决定谁可以贡献代码。
这些都是 Polyrepo
的优点,那为什么还有团队想要做一些改变呢?因为这种自主是通过隔离来提供的,而隔离会损害协作。更具体地说,这些是 Polyrepo
的常见缺点:
复杂的代码共享
为了跨存储库共享代码,你可能会为需要共享的代码创建一个单独的存储库。现在,你必须设置一系列工具和 CI 环境,在项目中添加提交配置,还需要配置打包和发布应用,以便其他存储库可以依赖到它。而且,让我们不得不开始核对跨存储库的第三方库的不兼容版本...
大量的代码重复
没有人愿意经历设置共享仓库的麻烦,因此各团队只是在各自的存储库中编写自己的共同服务和组件实现。这浪费了前期的时间,而且随着组件和服务因为维护带来的变化,安全和质量控制的负担也会增加。
维护跨存储库代码带来的代价高昂
当共享库修改了一个致命的错误或发生了破坏性的改变:开发人员需要设置其环境,以应用多个存储库的更改,并具有断开的修订历史记录。更不用说版本控制和发布应用等其它工作的协调。
不一致的工具
每个项目都使用自己的命令集来运行测试、构建、服务、验证、部署等。不一致性导致当从一个项目切换到另一个项目工作时,很难想起当前项目应该使用什么命令集,这造成了心智负担。
现在我们回过头来看 Monorepo
是如何解决这些问题的:
创建新项目没有太大的开销
使用现有的 CI 设置,如果所有项目都在同一存储库中,则无需单独发布版本软件包。
一致的版本
不需要再担心版本兼容问题,因为项目的第三方依赖库的版本冲突会导致报错。
跨项目协作
提交代码时不会发生破坏性的改变。
开发人员的可流动性
因为所有项目的构建流程和工具一致,所以开发人员可以很灵活的穿梭于各个项目之间。