Monorepo 导航器

monorepo-navigator
分类数据
作者Alireza Rezvani
许可MIT
评分4.90/5
使用9.0K

Monorepo Navigator

等级: POWERFUL
类别: Engineering
领域: Monorepo 架构 / 构建系统

---

概述

导航、管理并优化 monorepo。涵盖 Turborepo, Nx, pnpm workspaces 和 Lerna。实现跨包影响分析、仅针对受影响包进行选择性构建/测试、远程缓存、依赖图可视化,以及从多仓库到 monorepo 的结构化迁移。包含用于工作区感知开发的 Claude Code 配置。

---

核心能力

  • 跨包影响分析 — 确定共享包变更时哪些应用会受到影响
  • 选择性命令 — 仅对受影响的包运行测试/构建(而非全部运行)
  • 依赖图 — 将包关系可视化为 Mermaid 图表
  • 构建优化 — 远程缓存、增量构建、并行执行
  • 迁移 — 零历史丢失的逐步多仓库 $\rightarrow$ monorepo 迁移
  • 发布 — 使用 changesets 进行版本管理、预发布渠道、npm 发布工作流
  • Claude Code 配置 — 具备工作区感知的 CLAUDE.md,包含针对每个包的指令

---

使用场景

适用场景:

  • 多个包/应用共享代码(UI 组件、工具函数、类型定义、API 客户端)

  • 构建时间过长,因为任何变更都会导致全部重新构建

  • 从多个仓库迁移到单个仓库

  • 需要以协调的版本管理方式将包发布到 npm

  • 团队跨多个包工作,需要统一的工具链

不适用场景:

  • 没有共享包的单应用项目

  • 团队/项目边界完全隔离(使用 polyrepo 即可)

  • 共享代码极少,且拷贝粘贴的开销在可接受范围内

---

工具选择

| 工具 | 最适用场景 | 核心特性 |
|---|---|---|
| Turborepo | JS/TS monorepo,简单的流水线配置 | 顶级的远程缓存,极简配置 |
| Nx | 大型企业,插件生态系统 | 项目图谱,代码生成,affected 命令 |
| pnpm workspaces | 工作区协议,磁盘效率 | 使用 workspace:* 进行本地包引用 |
| Lerna | npm 发布,版本管理 | 批量发布,约定式提交 (conventional commits) |
| Changesets | 现代版本管理(优于 Lerna) | Changelog 生成,预发布渠道 |

大多数现代方案:pnpm workspaces + Turborepo + Changesets

---

Turborepo

$\rightarrow$ 详见 references/monorepo-tooling-reference.md

工作区分析器 (Workspace Analyzer)

bash
python3 scripts/monorepo_analyzer.py /path/to/monorepo
python3 scripts/monorepo_analyzer.py /path/to/monorepo --json

另请参阅 references/monorepo-patterns.md 以了解常见的架构和 CI 模式。

常见陷阱

| 陷阱 | 解决方案 |
|---|---|
| 在每个 PR 中运行 turbo run build 而不带 --filter | 在 CI 中始终使用 --filter=...[origin/main] |
| workspace:* 引用导致发布失败 | 使用 pnpm changeset publish — 它会自动将 workspace:* 替换为真实版本号 |
| 无关文件变更导致所有包重新构建 | 在 turbo.json 中调整 inputs,将文档、配置文件等排除在缓存计算之外 |
| 常见问题 | 解决方案 |
| :--- | :--- |
| 共享 tsconfig 导致单个包破坏所有类型检查 | 正确使用 extends —— 每个包继承根配置,但覆盖 rootDir / outDir |
| 迁移过程中丢失 git 历史 | 在合并前使用 git filter-repo --to-subdirectory-filter —— 绝不要手动移动文件 |
| CI 中远程缓存失效 | 检查 TURBO_TOKENTURBO_TEAM 环境变量;使用 turbo run build --summarize 验证 |
| CLAUDE.md 太泛 —— Claude 修改了错误的包 | 在每个包的 CLAUDE.md 中添加明确规则,如“在处理 X 时,仅修改 apps/X 中的文件” |

---

最佳实践

1. 根目录 CLAUDE.md 定义全局地图 —— 记录每个包的功能及其依赖规则
2. 各包 CLAUDE.md 定义具体规则 —— 规定允许/禁止的操作以及测试命令
3. 始终使用 --filter 限制命令范围 —— 每次变更都运行全部任务会违背 monorepo 的初衷
4. 远程缓存是必需的 —— 否则 monorepo 的 CI 速度会比多仓库 CI 更慢
5. 使用 Changesets 代替手动版本管理 —— 绝不要在 monorepo 中手动修改 package.json 的版本号
6. 共享配置置于根目录,在包中继承 —— 如 tsconfig.base.json, .eslintrc.base.js, jest.base.config.js
7. 合并共享包变更前进行影响分析 —— 运行 affected 检查,沟通影响范围(blast radius)
8. 保持 packages/types 为纯 TypeScript —— 不含运行时代码,无依赖,确保构建和类型检查速度极快