monorepo是一种开发策略,简单来说是一种开发思想,这个架构思想适用于任何语言的开发
一、核心概念
Monorepo 是一个软件开发策略,它将多个相关项目的代码 放在同一个版本控制仓库 中管理。与之相对的是 Multi-repo(多仓库),即每个项目都有自己的独立仓库。
二、直观比喻
百货商场 vs 独立专卖店
-
Monorepo(单体仓库) :像一个大型百货商场
-
所有商品(项目代码)都在同一栋建筑(仓库)里
-
共享基础设施(空调、电梯、安保)
-
顾客(开发者)可以一次逛完所有区域
-
容易实现跨楼层(跨项目)的促销活动(功能协作)
-
-
Multi-repo(多仓库) :像街上的独立专卖店
-
每个店(项目)有自己的店面(仓库)
-
需要分别管理水电、装修
-
要去不同的店需要走到街上(切换仓库)
-
联合促销需要复杂的协调
-
三、典型 Monorepo 项目结构
my-company-monorepo/
├── apps/ # 可独立运行的应用程序
│ ├── web/ # 主网站(Next.js)
│ ├── admin/ # 管理后台(React)
│ ├── mobile/ # 移动应用(React Native)
│ └── desktop/ # 桌面应用(Electron)
│
├── packages/ # 共享包/库
│ ├── ui/ # 共享UI组件库
│ ├── utils/ # 工具函数库
│ ├── config/ # 共享配置(ESLint、TypeScript等)
│ └── api-client/ # API客户端SDK
│
├── services/ # 后端微服务
│ ├── auth-service/
│ ├── payment-service/
│ └── notification-service/
│
├── scripts/ # 共享脚本
├── docs/ # 项目文档
├── package.json # 根目录的package.json(工作区配置)
└── turbo.json / nx.json # 构建系统配置
四、Monorepo 的主要优势
1. 代码共享与复用
-
共享组件、工具函数、类型定义可以直接引用
-
无需发布到 npm 或建立私有仓库
-
示例:
apps/web和apps/admin都直接导入packages/ui的组件
2. 一致性保证
-
统一代码规范(ESLint、Prettier)
-
统一依赖版本(避免版本冲突)
-
统一构建工具和流程
3. 跨项目重构和更新
-
一次提交可以更新多个相关项目
-
批量修改共享代码时,能立即发现所有受影响的地方
-
示例:更新一个共享组件,所有使用它的应用都能立即测试
4. 简化依赖管理
5. 统一的开发体验
-
一套命令管理所有项目
-
统一的 CI/CD 流水线
-
集中式的 issue 跟踪和文档
五、Monorepo 的挑战
1. 仓库体积庞大
-
Git 克隆时间增长
-
IDE 索引可能变慢
-
解决方案:Git 浅克隆、稀疏检出
2. 构建和测试复杂度
-
需要智能地只构建/测试受影响的部分
-
解决方案:使用 Turborepo、Nx、Bazel 等工具
3. 权限管理困难
-
难以精细控制谁可以访问哪个子目录
-
解决方案:Git 子模块、部分仓库镜像
4. 学习曲线
- 需要掌握特定的工具链和工作流程
六、Monorepo 工具生态
包管理 + 工作区
-
pnpm 、npm (v7+)、yarn(v1+):内置工作区支持
-
Lerna:传统的 Monorepo 管理工具
构建系统和任务运行器
-
Turborepo(Vercel):增量构建、缓存、任务管道
-
Nx(Nrwl):智能重建、依赖图可视化、代码生成
-
Rush(Microsoft):大型 Monorepo 解决方案
七、适用场景
适合 Monorepo:
-
多端应用(Web、移动端、桌面端)共享业务逻辑
-
微服务架构,服务间紧密协作
-
有大量共享组件和工具库的项目群
-
需要频繁跨项目修改和重构的团队
可能不适合 Monorepo:
-
完全不相关的项目集合
-
需要严格权限隔离的场景(如不同客户的项目)
-
超大规模代码库(Google、Facebook 有自己定制的解决方案)
八、知名公司的 Monorepo 实践
-
Google:所有代码在一个仓库(数十亿行代码)
-
Facebook/Meta:使用 Mercurial 管理超大型 Monorepo
-
Microsoft:Windows、Office 等使用超大 Monorepo
-
Shopify 、Airbnb 、Uber:前端采用 Monorepo
-
Vercel:开发并开源了 Turborepo
Monorepo 不是银弹 ,而是一种架构选择。它通过牺牲一定的隔离性 来换取更强的协作性和一致性。对于中大型项目团队,特别是那些需要频繁共享代码和协调发布的团队,Monorepo 能显著提升开发效率和代码质量。