为什么往 monorepo 方向演进
选择 monorepo,不是为了“更先进”,而是为了把多包协作里最常见的重复劳动砍掉。
当你的仓库里同时存在应用、类库、CLI、文档站,或者多个团队要共享同一套类型、配置、脚手架时,monorepo 的收益会很快超过它的管理成本。
这套模板解决的真实问题
1. 依赖和脚本不再分散
在 polyrepo 里,最常见的问题不是代码本身,而是:
- 每个仓库都要单独装依赖
- 每个仓库都维护一套 lint / typecheck / test 脚本
- 同样的工具链升级要重复做很多次
- 团队成员很难判断哪个仓库的规范才是“当前标准”
在 monorepo 里,这些东西可以收敛到一个根目录。
2. 跨包改动可以原子提交
如果一个接口变更同时影响:
packages/typespackages/sdkapps/webapps/server
那么在 monorepo 里,一次提交就能把它们一起改完、一起验证、一起回滚。对重构和版本审计都更友好。
3. 构建与测试更容易增量化
pnpm 负责 workspace 依赖管理,turborepo 负责任务编排和缓存,结果就是:
- 没改动的包不需要重复构建
- CI 可以按依赖图只跑受影响任务
- 大仓库也能保持比较稳定的反馈速度
这套模板的立场
这不是一个“什么都能配”的框架,而是一套偏实战、偏收敛的默认值:
| 维度 | 默认选择 |
|---|---|
| 包管理 | pnpm workspace |
| 任务编排 | turborepo |
| 语言 | TypeScript 优先 |
| 校验链路 | ESLint + Stylelint + typecheck + Vitest |
| 提交规范 | Husky + lint-staged + commitlint |
| 发包 | changesets |
| 命令入口 | repo 为主,repoctl / monorepo 为兼容入口 |
这些选择的目的只有一个:减少“每个项目重新想一遍”的成本。
什么时候适合用 monorepo
下面这些情况,适合直接上:
- 你要同时维护多个 npm 包
- 你有前后端、CLI、文档站共用一套类型或工具
- 你希望升级脚本、工程化配置时一次同步全仓
- 你有持续重构、跨包联动改动的需求
下面这些情况,不一定值得上:
- 只有一个很小的应用,没有共享代码需求
- 团队还没有接受统一规范的准备
- 构建链路本身还不稳定,先统一仓库只会放大问题
模板提供的补位能力
单纯有 monorepo 还不够,真正难的是“如何让它易用”。这个模板多补了三层东西:
1. 更短的日常命令
bash
pnpm setup
pnpm doctor
pnpm new
pnpm check不用先背完整 CLI,先把日常路径跑顺。
2. repo doctor 这种面向新人的诊断命令
它会直接回答这些问题:
- 你是不是站在仓库根目录
pnpm-workspace.yaml在不在- Node 版本对不对
- 有没有安装 CLI 依赖
- 根脚本齐不齐
repoctl.config.ts和monorepo.config.ts有没有冲突- Husky / lint-staged 链路是不是半残状态
3. repo upgrade 这种面向存量仓库的同步命令
当模板默认值变了,你不需要手抄配置,只要选择性同步标准资产。
实际收益通常体现在这里
| 场景 | Polyrepo 常见成本 | Monorepo 常见收益 |
|---|---|---|
| 工具链升级 | 多仓重复改配置 | 一次升级,多包受益 |
| 共享类型变更 | 多仓分别发版联调 | 一次改动,一次验证 |
| CI 反馈 | 每仓重复跑全量 | 利用缓存和依赖图做增量 |
| 新人接手 | 先理解多个仓库差异 | 先理解一套统一约定 |
