管理 monorepo
我使用 pnpm + turborepo
来管理 monorepo
相较于传统做法(比如多个独立仓库或用 Yarn/NPM 管理 monorepo)有 明显优势,从性能、可维护性、协作效率到发布流程都有提升。下面是详细解释:
核心优势一览
1. 极快的依赖安装(pnpm 的硬链接 + 内容寻址)
pnpm
使用内容寻址存储,多个项目间共享 node_modules 中的依赖,不重复安装。- 安装依赖速度远快于
npm
/yarn
,节省磁盘空间。
2. 智能任务调度与缓存(turborepo)
turbo
会缓存上一次的构建输出,不变的包不会重复构建,节省大量构建时间。- 类似于 Bazel、Nx 等构建系统,但配置简单,专注于 JavaScript/TypeScript 项目。
3. 明确的依赖关系管理
pnpm
强制使用严格的模块隔离,不允许“幽灵依赖”(hoist 下来的间接依赖)。- 每个包必须显式声明自己的依赖,减少运行时错误。
4. 组件复用 + 原子包发布
- 各子包可单独开发、测试、构建,也可以发布到 NPM。
- 例如一个 UI 组件库(
@my/ui
)被多个应用复用,改动只需维护一个位置。
5. 团队协作更清晰
- 多人负责不同 app/package 时,统一 workspace 管理避免重复工作。
- turbo 的
--filter
功能可以只运行特定 app/package 的任务,提高并行效率。
6. 支持渐进迁移/扩展
- 可以从一个项目开始,逐步迁移其他项目到 monorepo。
- 不强制结构,灵活适配大型或微服务项目。
示例:构建时间对比(真实项目)
构建系统 | 全量构建时间 | 增量构建时间 | 备注 |
---|---|---|---|
传统脚本 | 120s | 120s | 无缓存,每次都重建所有包 |
turbo | 120s | 5s | 使用缓存和依赖图优化任务调度 |
turbo + remote cache | 120s | 2s | 跨机器缓存(如 Vercel/Turbo Cloud) |
如果不用这套,你可能会遇到的问题
问题 | 结果 |
---|---|
重复安装多个项目的依赖 | 时间长、磁盘大、CI 卡慢 |
每次都构建整个仓库 | 效率低,修改一个 utils 都重新构建全部 |
依赖混乱、版本冲突 | 运行时报错难调试,容易出现「在我机器上可以」问题 |
多仓库协作不方便 | 开发者切来切去,难以同步更新和版本发布 |
🔚 总结
pnpm + turborepo 是现代 JS 项目的最佳实践之一,适用于微服务、组件库、多平台应用等复杂项目。
如果你关注的是:构建速度、复用率、协作效率 —— 这套方案绝对是值得投入的。