Monorepo架构
Monorepo 单仓库多项目架构
#tech / dev / pattern
#type / concept
#status / growing
Monorepo 架构
一句话定义
Monorepo 是将多个项目(应用、库、服务)放在同一个代码仓库中,通过共享依赖和统一工具链来管理的代码组织策略。
核心机制 / 工作原理
Monorepo vs 多仓库(Polyrepo)
| 维度 | Monorepo | Polyrepo |
|---|---|---|
| 代码复用 | 直接引用本地包,零发布成本 | 需发布 npm 包再引用 |
| 原子提交 | 一个 PR 可同时修改多个包 | 跨仓库需多个 PR 协调 |
| 统一版本 | 所有包共享同一 git 历史 | 各仓库独立版本管理 |
| 依赖管理 | 统一提升,避免重复安装 | 各自 node_modules,体积膨胀 |
| CI/CD | 需要增量构建,配置更复杂 | 每个仓库独立流水线,简单直接 |
| 权限控制 | 粒度粗(目录级) | 粒度细(仓库级) |
| 仓库体积 | 随项目增长会很大 | 各自独立,体积可控 |
核心挑战
1. 构建速度
随着包数量增加,全量构建时间线性增长。解决方案:
- 增量构建:只构建有变更的包及其依赖链
- 任务缓存:相同输入跳过重复构建(local cache + remote cache)
- 并行构建:无依赖关系的包并行执行
2. 依赖管理
- 需要 workspace 机制避免重复安装依赖
- 包之间的版本对齐问题
- Phantom dependency(幽灵依赖):未声明但因提升机制可访问的包
3. 代码边界
- 没有强制约束时,包之间可能产生不合理的耦合
- 需要 lint 规则或工具强制执行依赖方向
工具链
| 工具 | 定位 | 特点 |
|---|---|---|
| pnpm workspace | 依赖管理 | 硬链接节省磁盘,严格依赖隔离 |
| Turborepo | 任务编排 | 增量构建 + 远程缓存,配置简单 |
| Nx | 全功能平台 | 依赖图分析、增量构建、affected 检测、插件生态 |
| Lerna | 包发布 | 多包版本管理、changelog 生成(已被 Nx 团队接管) |
| Bazel/Buck | 大规模构建 | Google/Meta 级别的构建系统,学习曲线陡峭 |
典型目录结构
monorepo/
├── apps/
│ ├── web/ # 前端应用
│ ├── api/ # 后端服务
│ └── mobile/ # 移动端
├── packages/
│ ├── ui/ # 共享 UI 组件
│ ├── utils/ # 工具函数
│ ├── config/ # 共享配置(ESLint、TS)
│ └── contracts/ # API 契约
├── package.json # workspace 根配置
├── pnpm-workspace.yaml
└── turbo.json # Turborepo 配置
最小例子
pnpm workspace 配置:
# pnpm-workspace.yaml
packages:
- "apps/*"
- "packages/*"
// apps/web/package.json
{
"dependencies": {
"@myorg/ui": "workspace:*",
"@myorg/utils": "workspace:*"
}
}
pnpm install 会自动将 packages/ui 和 packages/utils 链接到 apps/web/node_modules,无需发布即可引用。
边界与常见误解
- Monorepo 不是单体应用:代码在一个仓库,但部署仍是独立的服务/应用
- 不是所有项目都适合:3 人以下团队、2-3 个项目时,Polyrepo 更简单
- Git 大文件问题:单仓库积累大量二进制文件会拖慢 clone;需用 Git LFS 或定期清理
- CI 复杂度被低估:需要 affected 检测、远程缓存、并行执行,否则 CI 时间会膨胀
- 权限控制有限:GitHub 等平台不支持目录级权限,敏感代码可能需要拆分
- Phantom dependency:pnpm 通过严格模式解决,npm/yarn 默认的提升机制会产生幽灵依赖
Contracts 在 Monorepo 中的角色
在 DDD 架构下,Contracts 包负责:
- API 契约:前后端通信的数据格式
- 数据验证:Zod Schema 用于请求验证
- 序列化格式:去除敏感信息的安全数据传输
- 版本控制:API 接口的版本管理
Domain 包负责业务逻辑和领域概念,两者职责不同。
Related notes
- Monorepo MOC
- Daily Use MOC
- [[pnpm|pnpm]]
- Turborepo
- [[nx|Nx]]