Skip to content

管理 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。
  • 不强制结构,灵活适配大型或微服务项目。

示例:构建时间对比(真实项目)

构建系统全量构建时间增量构建时间备注
传统脚本120s120s无缓存,每次都重建所有包
turbo120s5s使用缓存和依赖图优化任务调度
turbo + remote cache120s2s跨机器缓存(如 Vercel/Turbo Cloud)

如果不用这套,你可能会遇到的问题

问题结果
重复安装多个项目的依赖时间长、磁盘大、CI 卡慢
每次都构建整个仓库效率低,修改一个 utils 都重新构建全部
依赖混乱、版本冲突运行时报错难调试,容易出现「在我机器上可以」问题
多仓库协作不方便开发者切来切去,难以同步更新和版本发布

🔚 总结

pnpm + turborepo 是现代 JS 项目的最佳实践之一,适用于微服务、组件库、多平台应用等复杂项目。

如果你关注的是:构建速度、复用率、协作效率 —— 这套方案绝对是值得投入的。