架构设计
Turborepo 任务编排
turbo.json 的任务定义、依赖关系与缓存策略
作用
Turborepo 负责在 monorepo 里按依赖拓扑并行执行任务并缓存结果。根 package.json 的脚本大多是 turbo run <task> 的封装:
{
"scripts": {
"build": "turbo run build",
"dev": "turbo run dev",
"lint": "turbo run lint",
"test": "turbo run test",
"typecheck": "turbo run typecheck"
}
}任务定义(turbo.json)
{
"ui": "tui",
"tasks": {
"build": {
"dependsOn": ["^build"],
"inputs": ["$TURBO_DEFAULT$", ".env*"],
"outputs": ["dist/**", "build/**", ".next/**", "!.next/cache/**", ".vercel/**"]
},
"dev": {
"dependsOn": ["^build"],
"cache": false,
"persistent": true
},
"test": {
"dependsOn": [],
"inputs": ["src/**", "__tests__/**", "vitest.config.*", "vitest.setup.*"],
"outputs": ["coverage/**"]
},
"test:e2e": {
"dependsOn": ["^build"],
"cache": false,
"outputs": ["playwright-report/**", "test-results/**"]
},
"lint": { "dependsOn": ["^build"], "outputs": [] },
"typecheck": { "dependsOn": ["^build"], "outputs": [] },
"clean": { "cache": false }
}
}关键概念
dependsOn: ["^build"]
^ 表示「上游依赖包」。"^build" 即:执行本包的任务前,先把它依赖的所有包 build 完。
build/lint/typecheck/dev都依赖^build——因为它们需要依赖包先产出dist和类型声明;test不依赖^build(dependsOn: []),测试直接跑源码,更快。
cache
- 默认开启缓存:相同输入跳过执行,直接复用产物;
dev/test:watch/test:e2e/clean显式cache: false(持续运行或副作用任务不该缓存)。
inputs / outputs
inputs:哪些文件变化会让缓存失效。test只关心src、__tests__、vitest 配置;outputs:哪些产物纳入缓存。build缓存dist/**等,但排除.next/cache/**。
persistent
dev、test:watch 是常驻进程,标记 persistent: true,Turborepo 不会等它们「结束」。
不经过 Turborepo 的任务
格式化直接在根调用 Oxfmt,不走 turbo(Oxfmt 天然支持全仓库扫描):
{
"format": "oxfmt",
"format:check": "oxfmt --check"
}常见用法
# 只构建某个包及其上游依赖
pnpm --filter @skyroc/web-admin-layouts build
# 只对改动过的包跑 lint(结合 git)
turbo run lint --filter='[HEAD^1]'
# 强制忽略缓存
turbo run build --force