研发协作
Turborepo monorepo…
在 Turborepo monorepo 中配置 turbo.json 管道、远程缓存、自托管缓存和 CI 过滤,以优化构建并调试缓存未命中。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
Turborepo monorepo 构特定
解决思路
- 按 Workspace Root 组织项目:apps/ 下放 web、docs 等应用,packages/ 下放 ui、config 等包,每个子包包含 package.json,根目录包含 turbo.json 和 package.json。
- 在 turbo.json 的 pipeline 中使用核心字段:dependsOn 声明必须先完成的任务;cache 控制是否缓存输出;outputs 指定要缓存的文件;inputs 指定影响缓存 key 的文件;persistent 标记 dev server 等长运行任务。
- 配置根 turbo.json:设置 $schema 为 https://turbo.build/schema.json,globalDependencies 为 [.env, .env.local],globalEnv 为 [NODE_ENV, VERCEL_URL];build 配置 dependsOn 为 [^build]、outputs 为 [dist/**, .next/**, !.next/cache/**]、env 为 [API_URL, NEXT_PUBLIC_*];test 配置 dependsOn 为 [build]、outputs 为 [coverage/**]、inputs 为 [src/**/*.tsx, src/**/*.ts, test/**/*.ts];lint 配置 outputs 为 []、cache 为 true;typecheck 配置 dependsOn 为 [^build]、outputs 为 [];dev 配置 cache 为 false、persistent 为 true;clean 配置 cache 为 false。
- 配置包级 apps/web/turbo.json:设置 $schema 为 https://turbo.build/schema.json,extends 为 [//];pipeline.build.outputs 为 [.next/**, !.next/cache/**],env 为 [NEXT_PUBLIC_API_URL, NEXT_PUBLIC_ANALYTICS_ID];pipeline.test.outputs 为 [coverage/**],inputs 为 [src/**, tests/**, jest.config.js]。
- 使用 Vercel 远程缓存:运行 npx turbo login 登录;运行 npx turbo link 关联 Vercel 项目;运行 turbo build --remote-only 使用远程缓存;设置 TURBO_TOKEN=your-token 和 TURBO_TEAM=your-team。
- 在 GitHub Actions CI 中启用远程缓存:设置 env TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} 和 TURBO_TEAM: ${{ vars.TURBO_TEAM }};job build 使用 actions/checkout@v4、actions/setup-node@v4(node-version: 20、cache: npm);运行 npm ci;运行 npx turbo build --filter='...[origin/main]';运行 npx turbo test --filter='...[origin/main]'。
- 自托管远程缓存:用 Express 实现 GET /v8/artifacts/:hash 返回 createReadStream(filePath),PUT /v8/artifacts/:hash 用 mkdir 创建目录并用 createWriteStream 写入,返回 urls 数组,HEAD /v8/artifacts/:hash 用 fs.access 检查存在并返回 200 或 404;CACHE_DIR 为 ./cache,team 从 req.query.teamId 取默认 default;监听 3000。
- 为自托管缓存配置 turbo.json:设置 remoteCache 为 { signature: false }。
- 使用自托管缓存运行:turbo build --api="http://localhost:3000" --token="my-token" --team="my-team"。
- 使用过滤和范围:turbo build --filter=@myorg/web 构建指定包;turbo build --filter=@myorg/web... 构建该包及其依赖;turbo build --filter=...@myorg/ui 构建该包及其依赖者;turbo build --filter='...[origin/main]' 构建自 main 以来变更的包;turbo build --filter='./apps/*' 构建目录下包;turbo build --filter=@myorg/web --filter=@myorg/docs 组合过滤;turbo build --filter='!@myorg/docs' 排除包;turbo build --filter='...[HEAD^1]...' 包含变更包的依赖。
- 配置高级管道:build 使用 dependsOn 为 [^build]、outputs 为 [dist/**]、inputs 为 [$TURBO_DEFAULT$, !**/*.md, !**/*.test.*];test 使用 dependsOn 为 [^build]、outputs 为 [coverage/**]、inputs 为 [src/**, tests/**, *.config.*]、env 为 [CI, NODE_ENV];test:e2e 使用 dependsOn 为 [build]、outputs 为 []、cache 为 false;deploy 使用 dependsOn 为 [build, test, lint]、outputs 为 []、cache 为 false;db:generate 使用 cache 为 false;db:push 使用 cache 为 false、dependsOn 为 [db:generate];任务特定覆盖 @myorg/web#build 使用 dependsOn 为 [^build, @myorg/db#db:generate]、outputs 为 [.next/**]、env 为 [NEXT_PUBLIC_*]。
- 设置根 package.json:private 为 true,workspaces 为 [apps/*, packages/*];scripts 为 build: turbo build、dev: turbo dev、lint: turbo lint、test: turbo test、clean: turbo clean && rm -rf node_modules、format: prettier --write "**/*.{ts,tsx,md}"、changeset: changeset、version-packages: changeset version、release: turbo build --filter=./packages/* && changeset publish;devDependencies 包含 turbo: ^1.10.0、prettier: ^3.0.0、@changesets/cli: ^2.26.0;packageManager 为 npm@10.0.0。
- 调试缓存:turbo build --dry-run 查看将运行什么;turbo build --verbosity=2 显示带 hash 的详细输出;turbo build --graph 显示任务图;turbo build --force 强制不使用缓存;turbo build --summarize 显示缓存状态;TURBO_LOG_VERBOSITY=debug turbo build --filter=@myorg/web 调试特定任务。
- 遵循推荐做法:定义显式 inputs,避免缓存失效;使用 workspace protocol,如 @myorg/ui 使用 workspace:*;启用远程缓存,在 CI 和本地共享;在 CI 中过滤,只构建受影响的包;缓存构建输出,而不是源文件。
- 避免反模式:不要缓存 dev servers,应使用 persistent: true;不要在 env 中包含 secrets,使用运行时环境变量;不要忽略 dependsOn,否则导致竞态条件;不要过度过滤,否则可能漏掉依赖。
适用边界 · 注意事项
- 不适用于不使用 Turborepo 或非 monorepo 的项目。
- 无法使用远程缓存时(例如没有 Vercel 或自托管缓存、没有 TURBO_TOKEN/TURBO_TEAM),不要依赖 Vercel 远程缓存流程。
- 不要把长期运行的 dev server 放入缓存,也不要把 secrets 放进缓存 env;应分别使用 persistent: true 和运行时环境变量。