dependsOn 的三种写法
{
"tasks": {
"build": {
"dependsOn": [
"^build", // 1. 依赖包的 build
"lint", // 2. 自己的 lint
"//#generate-schema" // 3. 根 workspace 的 generate-schema
]
}
}
}
| 语法 | 含义 |
|---|---|
taskName | 同一个 workspace 的 task |
^taskName | 依赖包的 task(上游) |
//#taskName | 根 package.json 里的 script(不属于任何子包) |
经典 DAG 示例
workspace 依赖: web → ui → utils docs → ui → utils turbo.json: build: dependsOn ["^build"] test: dependsOn ["build"] lint: dependsOn [] pnpm turbo run test 的执行顺序: 1. utils:build (utils 无上游,先跑) 2. utils:test (自己的 build 完了) 3. ui:build (等 utils:build 完) 4. ui:test 5. web:build + docs:build (并行) 6. web:test + docs:test (并行)
Turbo 自动推导这个顺序——你只需写 dependsOn ["^build"],剩下的拓扑排序它搞定。
跨任务依赖
{
"tasks": {
"build": { "dependsOn": ["^build"] },
"typecheck": { "dependsOn": ["^build"] },
"test": {
"dependsOn": ["build", "typecheck"]
}
}
}
test 同时等自己的 build 和 typecheck——Turbo 只在两者都完成后才跑 test。
根 task(//# 前缀)
// 根 package.json { "scripts": { "generate-schema": "openapi-generate --out ./schemas" } }
// turbo.json { "tasks": { "//#generate-schema": { "inputs": ["openapi.yaml"], "outputs": ["schemas/**"] }, "build": { "dependsOn": ["//#generate-schema", "^build"] } } }
在根 workspace 跑一个"生成 schema"的任务,完成之后所有子包才开始 build——适合代码生成、migration 类前置步骤。
特殊的 inputs 和 outputs
{
"build": {
"inputs": [
"$TURBO_DEFAULT$", // 当前包的默认 inputs
"../shared-config/**" // 跨包引用文件
],
"outputs": [
"dist/**",
".next/**",
"!.next/cache/**" // 排除
]
}
}
$TURBO_DEFAULT$
代表当前包里所有被 git 追踪的文件——大多数时候的起点。
$TURBO_ROOT$
仓库根路径,用来引用根目录的文件,如
$TURBO_ROOT$/tsconfig.base.json。!pattern
排除——和 .gitignore 一样语义。
dry-run 验证图
pnpm turbo run build --dry-run
Tasks to Run
@myorg/utils#build
Task = build
Package = @myorg/utils
Hash = 5a2f1e8c...
Cached (Local) = false
Command = tsc
Dependencies = []
Dependendents = @myorg/ui#build
Inputs Files Considered = 23
Env Vars = []
@myorg/ui#build
Task = build
Package = @myorg/ui
Dependencies = [@myorg/utils#build]
Dependendents = [@myorg/web#build, @myorg/docs#build]
...
每个任务的 hash、依赖、被依赖、输入文件数——调试任务图的最佳工具。
JSON 输出分析
pnpm turbo run build --dry-run=json | jq '.tasks[] | {task: .taskId, hash: .hash, cached: .cache.local}'
适合 CI 里分析哪个任务 hash 变了、为什么没命中缓存。
图可视化
pnpm turbo run build --graph # 输出 DOT 格式到 stdout pnpm turbo run build --graph=graph.html # 生成 HTML + Mermaid 交互图 pnpm turbo run build --graph=graph.svg # SVG(需 graphviz)
HTML 图最实用
Turbo 2.x 生成的 HTML 图带 zoom/pan、hover 显示 hash——大 monorepo 排查"为什么这个任务跑了"时非常直观。
Turbo 2.x 生成的 HTML 图带 zoom/pan、hover 显示 hash——大 monorepo 排查"为什么这个任务跑了"时非常直观。
避免循环依赖
// ❌ 循环 { "tasks": { "build": { "dependsOn": ["test"] }, "test": { "dependsOn": ["build"] } } } // Turbo 会报错:Cyclic dependency detected: build → test → build
DAG 必须无环——设计时,把任务当成管线节点,前后关系清晰就不会成环。
并行度控制
pnpm turbo run build --concurrency=10 # 最多 10 个任务同时跑 pnpm turbo run build --concurrency=1 # 串行(debug 时有用) pnpm turbo run build --concurrency=100% # 用满 CPU(默认)
workspace 级别的覆盖
// turbo.json { "tasks": { "build": { "outputs": ["dist/**"] }, "@myorg/web#build": { // 只针对 web "dependsOn": ["^build", "@myorg/api#generate"], "outputs": [".next/**", "!.next/cache/**"] } } }
顶层的 build 是默认,具体包的 @myorg/web#build 覆盖——写特殊逻辑不影响其它包。
with-* 写法
{
"tasks": {
"dev": {
"cache": false,
"persistent": true,
"with": ["api#dev", "worker#dev"]
}
}
}
with 是 Turbo 2.x 新增——跑 web dev 时并发拉起 api dev 和 worker dev,适合开发期"前端+API+队列"三件套同时启动。
实战:一个完整的 turbo.json
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": [".env", "tsconfig.base.json"],
"globalEnv": ["NODE_ENV", "VERCEL_ENV"],
"tasks": {
"build": {
"dependsOn": ["^build", "//#generate-schema"],
"inputs": ["$TURBO_DEFAULT$", "!**/*.md"],
"outputs": ["dist/**", ".next/**", "!.next/cache/**"],
"env": ["NEXT_PUBLIC_*"]
},
"test": {
"dependsOn": ["build"],
"outputs": ["coverage/**"]
},
"typecheck": {
"dependsOn": ["^build"]
},
"lint": {},
"dev": {
"cache": false,
"persistent": true
},
"//#generate-schema": {
"inputs": ["openapi.yaml"],
"outputs": ["packages/api-types/src/**"]
}
}
}
读完这份配置,任何人都能理解整个 monorepo 的构建流程——比读 300 行 bash 脚本清晰得多。
本章小结
dependsOn三语法:task(自己)、^task(依赖包)、//#task(根)$TURBO_DEFAULT$当前包默认 inputs,$TURBO_ROOT$引用根文件--dry-run/--graph是画图调试任务依赖的利器package#task格式写包专属配置覆盖默认- Turbo 2 的
with让开发期多任务共同启动更方便