研发协作
搭建或优化多包 Monorepo 时,用…
适用于新建或迁移多包仓库、优化 monorepo 构建测试性能、管理共享依赖、设置 CI/CD 与包发布流程。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
搭建或优化多包 Monorepo 时,用特定
解决思路
- 新建 Turborepo monorepo:运行 `npx create-turbo@latest my-monorepo`,然后 `cd my-monorepo`。
- 采用目录结构:`apps/` 放应用(如 `web`、`docs`),`packages/` 放共享包(如 `ui`、`config`、`tsconfig`),根目录放 `turbo.json` 和根 `package.json`。
- 配置 `turbo.json`:设置 `$schema` 为 `https://turbo.build/schema.json`,`globalDependencies` 为 `["**/.env.*local"]`。
- 在 `turbo.json` 的 `pipeline.build` 中设置 `dependsOn` 为 `["^build"]`,`outputs` 为 `["dist/**", ".next/**", "!.next/cache/**"]`。
- 在 `turbo.json` 的 `pipeline.test` 中设置 `dependsOn` 为 `["build"]`,`outputs` 为 `["coverage/**"]`。
- 在 `turbo.json` 的 `pipeline.lint` 中设置 `outputs` 为 `[]`。
- 在 `turbo.json` 的 `pipeline.dev` 中设置 `cache` 为 `false`,`persistent` 为 `true`。
- 在 `turbo.json` 的 `pipeline.type-check` 中设置 `dependsOn` 为 `["^build"]`,`outputs` 为 `[]`。
- 配置根 `package.json`:`name` 为 `my-monorepo`,`private` 为 `true`,`workspaces` 为 `["apps/*", "packages/*"]`。
- 在根 `package.json` 的 `scripts` 中设置:`build` 为 `turbo run build`,`dev` 为 `turbo run dev`,`test` 为 `turbo run test`,`lint` 为 `turbo run lint`,`format` 为 `prettier --write "**/*.{ts,tsx,md}"`,`clean` 为 `turbo run clean && rm -rf node_modules`。
- 在根 `package.json` 的 `devDependencies` 中加入 `turbo`、`prettier`、`typescript`,并设置 `packageManager` 为 `pnpm@8.0.0`。
- 配置共享包 `packages/ui/package.json`:`name` 为 `@repo/ui`,`version` 为 `0.0.0`,`private` 为 `true`,`main`/`types`/`exports` 指向 `dist`。
- 在 `packages/ui/package.json` 的 `scripts` 中设置:`build` 为 `tsup src/index.ts --format esm,cjs --dts`,`dev` 为 `tsup src/index.ts --format esm,cjs --dts --watch`,`lint` 为 `eslint src/`,`type-check` 为 `tsc --noEmit`。
- 在 `packages/ui/package.json` 中用 `workspace:*` 引用 `@repo/tsconfig` 作为 devDependency,并声明 `tsup`、`typescript`、`react` 依赖。
- 选择包管理器:优先用 `pnpm workspaces`,也可用 `npm workspaces` 或 `Yarn workspaces`。
- 选择构建系统:优先用 `Turborepo`,功能更复杂时可用 `Nx`,`Lerna` 较旧且处于维护模式。
- 当上面的导航层信息不足时,阅读 `references/details.md` 获取详细模式和工作示例。
- 锁定依赖版本:在 workspace 中保持一致版本。
- 共享配置:集中管理 ESLint、TypeScript、Prettier 配置。
- 维护依赖图:保持依赖图无环,避免循环依赖。
- 有效缓存:正确配置 Turborepo 的 inputs/outputs。
- 类型安全:在前端与后端之间共享类型。
- 测试策略:在 packages 中写单元测试,在 apps 中写 E2E 测试。
- 文档:为每个 package 编写 README。
- 发布策略:使用 changesets 进行版本管理。
- 避免循环依赖:不要让 A 依赖 B 且 B 依赖 A。
- 避免幻影依赖:不要使用未在 package.json 中声明的依赖。
- 避免缓存输入错误:不要把 Turborepo inputs 中需要的文件遗漏。
- 避免过度共享:不要把本应分离的代码强行共享。
- 避免共享不足:不要在多个 package 中重复代码。
- 避免大型 monorepo 构建变慢:使用适当工具,不要缺少缓存/任务编排。
- 使用 Changesets 发布包:运行 `pnpm add -Dw @changesets/cli`,然后 `pnpm changeset init`。
- 创建 changeset:运行 `pnpm changeset`。
- 提升版本:运行 `pnpm changeset version`。
- 发布:运行 `pnpm changeset publish`。
- 配置 GitHub Actions 发布:使用 `changesets/action@v1`,设置 `publish` 为 `pnpm release`,并提供 `GITHUB_TOKEN` 与 `NPM_TOKEN` 环境变量。
适用边界 · 注意事项
- 单包或少量包、无需共享依赖和原子提交时,引入 monorepo 会增加不必要复杂度。
- 团队无法维护专用工具链、CI 缓存和访问控制,或需要严格仓库级权限隔离时,不适合使用。
- 已有多仓库流程成熟且迁移成本高于收益时,不必迁移到 monorepo。