Monorepo的真相:为什么大部分团队都用错了

Monorepo 最近几年成了前端工程化的显学。Google、Meta、微软都在用,Turborepo、Nx 这些工具层出不穷,到处都在讲 Monorepo 的好处。但我观察下来,大部分团队引入 Monorepo 之后,要么是用成了"巨型仓库",要么是过度拆分变成了"伪 Monorepo"。

真正的问题不是 Monorepo 本身,而是大家搞错了它的适用场景。

 

先说结论:Monorepo 不是银弹

 

很多团队看到 Google 用 Monorepo 管理几十亿行代码,就觉得自己也该用。但这里有个认知偏差:Google 的 Monorepo 是为了解决他们特有的问题——跨团队代码共享和依赖管理

你的团队有这个问题吗?

大部分团队的实际情况是:
- 前端就 3-5 个人,管理的项目不超过 10 个
- 业务相对独立,跨项目共享的代码不多
- 没有复杂的内部依赖关系
- 团队协作流程还没稳定下来

这种情况下,Monorepo 带来的复杂度远大于收益。

我见过一个团队,5 个前端工程师,管理着 3 个业务项目和 2 个组件库,硬是搞了一个 Monorepo。结果呢?CI/CD 配置复杂了 3 倍,每次发布都要小心翼翼地确认依赖关系,反而降低了开发效率。

 

Monorepo 的真实成本

 

很多文章只讲 Monorepo 的好处,但很少有人算过它的成本。

 

1. 工具链的复杂度暴增

 

Monorepo 需要配套的工具链:
- 构建工具(Turborepo、Nx、Rush)
- 依赖管理(pnpm workspace、yarn workspace)
- CI/CD 配置(增量构建、缓存策略)
- 代码审查流程(CODEOWNERS、路径权限)

每一项都需要学习成本和维护成本。如果团队没有专门的工程效能负责人,这些成本会分散到每个开发者身上。

我在金融业务中看到过一个反例:团队引入 Turborepo 之后,发现远程缓存经常失效,导致 CI 时间反而变长了。排查了一个月才发现是 cache key 配置有问题。这个问题在多仓库方案下根本不会出现。

 

2. Git 操作变慢

 

Monorepo 的仓库体积会随着项目增长而膨胀。即使用了 Git LFS 或者 Partial Clone,`git status`、`git log` 这些基础操作还是会变慢。

你可能会说"可以用 sparse checkout"。但这又引入了新的复杂度——开发者需要理解 sparse checkout 的概念,配置本地环境,维护 `.git/info/sparse-checkout` 文件。

这些都是隐形成本。

 

3. 权限管理的困境

 

在多仓库方案下,权限管理很简单:A 项目的仓库只给 A 团队权限,B 项目的仓库只给 B 团队权限。

但在 Monorepo 下,所有人都能看到所有代码。你可能会说"可以用 CODEOWNERS",但这只能控制 PR 的审查权限,无法控制代码的访问权限。

在金融业务中,有些敏感业务逻辑是不能让所有人看到的。这时候 Monorepo 就成了安全隐患。

 

4. 发布流程的复杂化

 

多仓库方案下,每个项目的发布是独立的。想发哪个发哪个,互不影响。

Monorepo 下,你需要考虑:
- 哪些包需要一起发布?
- 版本号怎么管理?(统一版本 vs 独立版本)
- 如何避免误发布?
- 回滚策略是什么?

Lerna、Changesets 这些工具能解决一部分问题,但又引入了新的学习成本。

 

什么时候应该用 Monorepo?

 

我不是说 Monorepo 一无是处,而是说它有明确的适用场景。

 

场景 1:高度耦合的项目

 

如果你的项目之间有大量的代码共享和依赖关系,Monorepo 能简化依赖管理。

典型案例是组件库 + 业务应用。组件库需要频繁迭代,业务应用需要及时跟进。在多仓库方案下,你需要:
1. 修改组件库代码
2. 发布新版本到 npm
3. 更新业务应用的依赖
4. 测试兼容性

在 Monorepo 下,这个流程简化为:
1. 修改组件库代码
2. 本地测试业务应用
3. 一起提交

这种情况下,Monorepo 确实能提升效率。

 

场景 2:需要原子性提交

 

如果你的变更需要跨多个项目,并且这些变更必须同时生效,Monorepo 是更好的选择。

比如 API 接口的破坏性变更。在多仓库方案下,你需要协调多个仓库的发布顺序,确保兼容性。在 Monorepo 下,一个 commit 就能保证所有变更的原子性。

 

场景 3:团队规模足够大

 

如果你的团队有 20+ 工程师,管理着 10+ 个项目,并且有专门的工程效能团队,Monorepo 的收益会大于成本。

但如果团队只有 5-10 人,Monorepo 可能会成为负担。

 

大部分团队的误区

 

 

误区 1:为了代码共享而用 Monorepo

 

很多团队引入 Monorepo 的理由是"方便代码共享"。但代码共享不一定需要 Monorepo。

npm 私有仓库、Git submodule、甚至直接 copy 代码,都能实现代码共享。关键是要评估成本和收益。

如果共享的代码不多,或者变更频率不高,多仓库 + npm 私有仓库可能是更简单的方案。

 

误区 2:把所有项目都塞进一个仓库

 

有些团队理解的 Monorepo 就是"把所有代码放在一个仓库里"。这种做法往往适得其反。

Monorepo 不是"一个大仓库",而是"一个统一管理的代码库"。关键是要有清晰的边界和依赖关系。

如果你的项目之间没有依赖关系,完全独立,那么强行放在一个仓库里只会增加复杂度。

 

误区 3:忽视工具链的学习成本

 

Monorepo 的工具链(Turborepo、Nx、Lerna)都有自己的概念和配置方式。团队需要时间学习和适应。

我见过一个团队,引入 Nx 之后,因为不熟悉 `project.json` 的配置方式,导致构建经常出问题。最后花了一个月时间才稳定下来。

这个成本在多仓库方案下是不存在的。

 

我的建议

 

如果你的团队正在考虑 Monorepo,先问自己几个问题:

1. 我们的项目之间有多少共享代码? 如果少于 20%,可能不需要 Monorepo。
2. 我们需要原子性提交吗? 如果不需要,多仓库方案可能更简单。
3. 团队有没有人愿意负责工具链维护? 如果没有,Monorepo 会成为负担。
4. 我们的 CI/CD 能支持 Monorepo 吗? 如果不能,需要先投入时间升级基础设施。

对于中小团队(10 人以下),我的建议是:
- 业务项目用多仓库
- 共享组件库用独立仓库 + npm 私有仓库
- 等团队规模扩大、依赖关系复杂化之后,再考虑 Monorepo

对于大型团队(20 人以上),可以考虑:
- 按业务域拆分多个 Monorepo(而不是一个巨型 Monorepo)
- 投入专门的人力维护工具链
- 建立完善的发布和回滚流程

 

结语

 

Monorepo 不是架构演进的终点,只是一种工程实践方案。它能解决特定场景下的问题,但也会带来新的复杂度。

关键是要根据团队的实际情况做选择。不要因为大公司在用,就盲目跟风。也不要因为工具链复杂,就完全排斥。

技术选型没有银弹,只有权衡。

你的团队真的需要 Monorepo 吗?

You voted 5. Total votes: 25

添加新评论