Turborepo构建系统技能 turborepo

Turborepo 是一个专为 JavaScript/TypeScript monorepo 设计的构建系统,通过智能缓存和并行任务执行来优化开发流程。它支持任务依赖管理、缓存机制、远程缓存、包过滤和 CI 集成,帮助团队高效管理代码库和构建过程。关键词:Turborepo, monorepo, 构建系统, 缓存, 并行任务, JavaScript, TypeScript, 任务管理, CI/CD。

DevOps 0 次安装 0 次浏览 更新于 3/7/2026

name: turborepo description: | Turborepo monorepo 构建系统指南。触发于:turbo.json、任务管道、dependsOn、缓存、远程缓存、“turbo” CLI、–filter、–affected、CI 优化、环境变量、内部包、monorepo 结构/最佳实践和边界。

当用户:配置任务/工作流/管道、创建包、设置 monorepo、在应用间共享代码、运行变更/受影响包、调试缓存或有应用/包目录时使用。 metadata: version: 2.8.3-canary.4

Turborepo 技能

用于 JavaScript/TypeScript monorepo 的构建系统。Turborepo 缓存任务输出,并基于依赖图并行运行任务。

重要:包任务,非根任务

不要创建根任务。始终创建包任务。

创建任务/脚本/管道时,您必须:

  1. 将脚本添加到每个相关包的 package.json
  2. 在根 turbo.json 中注册任务
  3. package.json 仅通过 turbo run <task> 委托

不要将任务逻辑放在根 package.json 中。这会破坏 Turborepo 的并行化。

// 这样做:每个包中的脚本
// apps/web/package.json
{ "scripts": { "build": "next build", "lint": "eslint .", "test": "vitest" } }

// apps/api/package.json
{ "scripts": { "build": "tsc", "lint": "eslint .", "test": "vitest" } }

// packages/ui/package.json
{ "scripts": { "build": "tsc", "lint": "eslint .", "test": "vitest" } }
// turbo.json - 注册任务
{
  "tasks": {
    "build": { "dependsOn": ["^build"], "outputs": ["dist/**"] },
    "lint": {},
    "test": { "dependsOn": ["build"] }
  }
}
// 根 package.json - 仅委托,无任务逻辑
{
  "scripts": {
    "build": "turbo run build",
    "lint": "turbo run lint",
    "test": "turbo run test"
  }
}
// 不要这样做 - 破坏并行化
// 根 package.json
{
  "scripts": {
    "build": "cd apps/web && next build && cd ../api && tsc",
    "lint": "eslint apps/ packages/",
    "test": "vitest"
  }
}

根任务(//#taskname)仅适用于确实无法存在于包中的任务(罕见)。

次要规则:turbo run 对比 turbo

在写入代码的命令中始终使用 turbo run

// package.json - 始终使用 "turbo run"
{
  "scripts": {
    "build": "turbo run build"
  }
}
# CI 工作流 - 始终使用 "turbo run"
- run: turbo run build --affected

简写 turbo <tasks> 仅适用于一次性终端命令,由人类或代理直接键入。切勿在 package.json、CI 或脚本中写入 turbo build

快速决策树

“我需要配置任务”

配置任务?
├─ 定义任务依赖 → references/configuration/tasks.md
├─ 检查/类型检查(并行 + 缓存)→ 使用 Transit Nodes 模式(见下文)
├─ 指定构建输出 → references/configuration/tasks.md#outputs
├─ 处理环境变量 → references/environment/RULE.md
├─ 设置开发/监视任务 → references/configuration/tasks.md#persistent
├─ 包特定配置 → references/configuration/RULE.md#package-configurations
└─ 全局设置(cacheDir, daemon)→ references/configuration/global-options.md

“我的缓存不起作用”

缓存问题?
├─ 任务运行但输出未恢复 → 缺少 `outputs` 键
├─ 意外缓存未命中 → references/caching/gotchas.md
├─ 需要调试哈希输入 → 使用 --summarize 或 --dry
├─ 想完全跳过缓存 → 使用 --force 或 cache: false
├─ 远程缓存不起作用 → references/caching/remote-cache.md
└─ 环境导致未命中 → references/environment/gotchas.md

“我想只运行变更的包”

只运行变更的包?
├─ 变更包 + 依赖项(推荐)→ turbo run build --affected
├─ 自定义基础分支 → --affected --affected-base=origin/develop
├─ 手动 git 比较 → --filter=...[origin/main]
└─ 查看所有过滤选项 → references/filtering/RULE.md

--affected 是只运行变更包的主要方式。 它会自动与默认分支比较并包括依赖项。

“我想过滤包”

过滤包?
├─ 只变更包 → --affected(见上文)
├─ 按包名 → --filter=web
├─ 按目录 → --filter=./apps/*
├─ 包 + 依赖项 → --filter=web...
├─ 包 + 依赖项 → --filter=...web
└─ 复杂组合 → references/filtering/patterns.md

“环境变量不起作用”

环境问题?
├─ 运行时变量不可用 → 严格模式过滤(默认)
├─ 缓存命中但环境错误 → 变量不在 `env` 键中
├─ .env 变更未导致重建 → .env 不在 `inputs` 中
├─ CI 变量缺失 → references/environment/gotchas.md
└─ 框架变量(NEXT_PUBLIC_*)→ 通过推断自动包含

“我需要设置 CI”

CI 设置?
├─ GitHub Actions → references/ci/github-actions.md
├─ Vercel 部署 → references/ci/vercel.md
├─ CI 中的远程缓存 → references/caching/remote-cache.md
├─ 只构建变更包 → --affected 标志
├─ 跳过不必要的构建 → turbo-ignore(references/cli/commands.md)
└─ 无变更时跳过容器设置 → turbo-ignore

“我想在开发时监视变更”

监视模式?
├─ 变更时重新运行任务 → turbo watch(references/watch/RULE.md)
├─ 带依赖的开发服务器 → 使用 `with` 键(references/configuration/tasks.md#with)
├─ 依赖变更时重启开发服务器 → 使用 `interruptible: true`
└─ 持久开发任务 → 使用 `persistent: true`

“我需要创建/结构化包”

包创建/结构?
├─ 创建内部包 → references/best-practices/packages.md
├─ 仓库结构 → references/best-practices/structure.md
├─ 依赖管理 → references/best-practices/dependencies.md
├─ 最佳实践概述 → references/best-practices/RULE.md
├─ JIT 对比编译包 → references/best-practices/packages.md#compilation-strategies
└─ 在应用间共享代码 → references/best-practices/RULE.md#package-types

“我该如何结构化我的 monorepo?”

Monorepo 结构?
├─ 标准布局(apps/, packages/)→ references/best-practices/RULE.md
├─ 包类型(应用对比库)→ references/best-practices/RULE.md#package-types
├─ 创建内部包 → references/best-practices/packages.md
├─ TypeScript 配置 → references/best-practices/structure.md#typescript-configuration
├─ ESLint 配置 → references/best-practices/structure.md#eslint-configuration
├─ 依赖管理 → references/best-practices/dependencies.md
└─ 强制包边界 → references/boundaries/RULE.md

“我想强制架构边界”

强制边界?
├─ 检查违规 → turbo boundaries
├─ 标记包 → references/boundaries/RULE.md#tags
├─ 限制哪些包可以导入其他包 → references/boundaries/RULE.md#rule-types
└─ 防止跨包文件导入 → references/boundaries/RULE.md

关键反模式

在代码中使用 turbo 简写

在 package.json 脚本和 CI 管道中推荐使用 turbo run 简写 turbo <task> 旨在用于交互式终端。

// 错误 - 在 package.json 中使用简写
{
  "scripts": {
    "build": "turbo build",
    "dev": "turbo dev"
  }
}

// 正确
{
  "scripts": {
    "build": "turbo run build",
    "dev": "turbo run dev"
  }
}
# 错误 - 在 CI 中使用简写
- run: turbo build --affected

# 正确
- run: turbo run build --affected

根脚本绕过 Turbo

package.json 脚本必须委托给 turbo run,而不是直接运行任务。

// 错误 - 完全绕过 turbo
{
  "scripts": {
    "build": "bun build",
    "dev": "bun dev"
  }
}

// 正确 - 委托给 turbo
{
  "scripts": {
    "build": "turbo run build",
    "dev": "turbo run dev"
  }
}

使用 && 链接 Turbo 任务

不要用 && 链接 turbo 任务。让 turbo 协调。

// 错误 - turbo 任务未使用 turbo run
{
  "scripts": {
    "changeset:publish": "bun build && changeset publish"
  }
}

// 正确
{
  "scripts": {
    "changeset:publish": "turbo run build && changeset publish"
  }
}

prebuild 脚本手动构建依赖项

prebuild 这样手动构建其他包的脚本绕过 Turborepo 的依赖图。

// 错误 - 手动构建依赖项
{
  "scripts": {
    "prebuild": "cd ../../packages/types && bun run build && cd ../utils && bun run build",
    "build": "next build"
  }
}

然而,修复取决于工作区依赖是否声明:

  1. 如果依赖已声明(例如,package.json 中的 "@repo/types": "workspace:*"),移除 prebuild 脚本。Turbo 的 dependsOn: ["^build"] 会自动处理。

  2. 如果依赖未声明prebuild 存在是因为没有依赖关系 ^build 不会触发。修复方法是:

    • 将依赖添加到 package.json:"@repo/types": "workspace:*"
    • 然后移除 prebuild 脚本
// 正确 - 声明依赖,让 turbo 处理构建顺序
// package.json
{
  "dependencies": {
    "@repo/types": "workspace:*",
    "@repo/utils": "workspace:*"
  },
  "scripts": {
    "build": "next build"
  }
}

// turbo.json
{
  "tasks": {
    "build": {
      "dependsOn": ["^build"]
    }
  }
}

关键洞察: ^build 只在列为依赖的包中运行构建。没有依赖声明 = 没有自动构建顺序。

过于宽泛的 globalDependencies

globalDependencies 影响所有包中的所有任务。要具体。

// 错误 - 重锤,影响所有哈希
{
  "globalDependencies": ["**/.env.*local"]
}

// 更好 - 移动到任务级输入
{
  "globalDependencies": [".env"],
  "tasks": {
    "build": {
      "inputs": ["$TURBO_DEFAULT$", ".env*"],
      "outputs": ["dist/**"]
    }
  }
}

重复的任务配置

寻找跨任务可以合并的重复配置。Turborepo 支持共享配置模式。

// 错误 - 跨任务重复的 env 和 inputs
{
  "tasks": {
    "build": {
      "env": ["API_URL", "DATABASE_URL"],
      "inputs": ["$TURBO_DEFAULT$", ".env*"]
    },
    "test": {
      "env": ["API_URL", "DATABASE_URL"],
      "inputs": ["$TURBO_DEFAULT$", ".env*"]
    },
    "dev": {
      "env": ["API_URL", "DATABASE_URL"],
      "inputs": ["$TURBO_DEFAULT$", ".env*"],
      "cache": false,
      "persistent": true
    }
  }
}

// 更好 - 为共享配置使用 globalEnv 和 globalDependencies
{
  "globalEnv": ["API_URL", "DATABASE_URL"],
  "globalDependencies": [".env*"],
  "tasks": {
    "build": {},
    "test": {},
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

何时使用全局对比任务级:

  • globalEnv / globalDependencies - 影响所有任务,用于真正的共享配置
  • 任务级 env / inputs - 当只有特定任务需要时使用

非反模式:大型 env 数组

大型 env 数组(甚至 50+ 变量)不是问题。这通常意味着用户彻底声明了构建的环境依赖。不要将此标记为问题。

使用 --parallel 标志

--parallel 标志绕过 Turborepo 的依赖图。如果任务需要并行执行,请正确配置 dependsOn

# 错误 - 绕过依赖图
turbo run lint --parallel

# 正确 - 配置任务以允许并行执行
# 在 turbo.json 中,适当设置 dependsOn(或使用 transit nodes)
turbo run lint

根 turbo.json 中的包特定任务覆盖

当多个包需要不同的任务配置时,使用包配置(每个包中的 turbo.json)而不是在根 turbo.json 中混淆 package#task 覆盖。

// 错误 - 根 turbo.json 有许多包特定覆盖
{
  "tasks": {
    "test": { "dependsOn": ["build"] },
    "@repo/web#test": { "outputs": ["coverage/**"] },
    "@repo/api#test": { "outputs": ["coverage/**"] },
    "@repo/utils#test": { "outputs": [] },
    "@repo/cli#test": { "outputs": [] },
    "@repo/core#test": { "outputs": [] }
  }
}

// 正确 - 使用包配置
// 根 turbo.json - 仅基本配置
{
  "tasks": {
    "test": { "dependsOn": ["build"] }
  }
}

// packages/web/turbo.json - 包特定覆盖
{
  "extends": ["//"],
  "tasks": {
    "test": { "outputs": ["coverage/**"] }
  }
}

// packages/api/turbo.json
{
  "extends": ["//"],
  "tasks": {
    "test": { "outputs": ["coverage/**"] }
  }
}

包配置的好处:

  • 保持配置接近其影响的代码
  • 根 turbo.json 保持清洁并专注于基本模式
  • 更容易理解每个包的特殊之处
  • $TURBO_EXTENDS$ 一起工作以继承和扩展数组

何时在根中使用 package#task

  • 单个包需要唯一依赖(例如,"deploy": { "dependsOn": ["web#build"] }
  • 迁移时的临时覆盖

references/configuration/RULE.md#package-configurations 获取完整细节。

inputs 中使用 ../ 遍历出包

不要使用像 ../ 这样的相对路径引用包外文件。使用 $TURBO_ROOT$

// 错误 - 遍历出包
{
  "tasks": {
    "build": {
      "inputs": ["$TURBO_DEFAULT$", "../shared-config.json"]
    }
  }
}

// 正确 - 为仓库根使用 $TURBO_ROOT$
{
  "tasks": {
    "build": {
      "inputs": ["$TURBO_DEFAULT$", "$TURBO_ROOT$/shared-config.json"]
    }
  }
}

文件生成任务缺少 outputs

在标记缺少 outputs 之前,检查任务实际产生什么:

  1. 阅读包的脚本(例如,"build": "tsc", "test": "vitest"
  2. 确定是否写入文件到磁盘或仅输出到 stdout
  3. 仅当任务产生应缓存的文件时才标记
// 错误:构建产生文件但未缓存
{
  "tasks": {
    "build": {
      "dependsOn": ["^build"]
    }
  }
}

// 正确:构建输出被缓存
{
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**"]
    }
  }
}

按框架的常见输出:

  • Next.js: [".next/**", "!.next/cache/**"]
  • Vite/Rollup: ["dist/**"]
  • tsc: ["dist/**"] 或自定义 outDir

TypeScript --noEmit 仍可能产生缓存文件:

当 tsconfig.json 中的 incremental: truetsc --noEmit 即使不发出 JS 也写入 .tsbuildinfo 文件。在假设无输出前检查 tsconfig:

// 如果 tsconfig 有 incremental: true,tsc --noEmit 产生缓存文件
{
  "tasks": {
    "typecheck": {
      "outputs": ["node_modules/.cache/tsbuildinfo.json"] // 或 tsBuildInfoFile 指向的任何地方
    }
  }
}

确定 TypeScript 任务的正确输出:

  1. 检查 tsconfig 中是否启用 incrementalcomposite
  2. 检查 tsBuildInfoFile 的自定义缓存位置(默认:与 outDir 一起或在项目根)
  3. 如果没有增量模式,tsc --noEmit 不产生文件

^build 对比 build 混淆

{
  "tasks": {
    // ^build = 先在依赖项中运行构建(此包导入的其他包)
    "build": {
      "dependsOn": ["^build"]
    },
    // build(无 ^)= 先在同一包中运行构建
    "test": {
      "dependsOn": ["build"]
    },
    // pkg#task = 特定包的任务
    "deploy": {
      "dependsOn": ["web#build"]
    }
  }
}

环境变量未哈希

// 错误:API_URL 变更不会导致重建
{
  "tasks": {
    "build": {
      "outputs": ["dist/**"]
    }
  }
}

// 正确:API_URL 变更使缓存无效
{
  "tasks": {
    "build": {
      "outputs": ["dist/**"],
      "env": ["API_URL", "API_KEY"]
    }
  }
}

.env 文件不在输入中

Turbo 不加载 .env 文件 - 您的框架加载。但 Turbo 需要知道变更:

// 错误:.env 变更不使缓存无效
{
  "tasks": {
    "build": {
      "env": ["API_URL"]
    }
  }
}

// 正确:.env 文件变更使缓存无效
{
  "tasks": {
    "build": {
      "env": ["API_URL"],
      "inputs": ["$TURBO_DEFAULT$", ".env", ".env.*"]
    }
  }
}

Monorepo 中的根 .env 文件

仓库根部的 .env 文件是反模式 — 即使对于小型 monorepo 或起始模板。它创建包之间的隐式耦合,并使哪些包依赖哪些变量不明确。

// 错误 - 根 .env 隐式影响所有包
my-monorepo/
├── .env              # 哪些包使用这个?
├── apps/
│   ├── web/
│   └── api/
└── packages/

// 正确 - .env 文件在需要的包中
my-monorepo/
├── apps/
│   ├── web/
│   │   └── .env      # 明确:web 需要 DATABASE_URL
│   └── api/
│       └── .env      # 明确:api 需要 API_KEY
└── packages/

.env 的问题:

  • 不明确哪些包使用哪些变量
  • 所有包获得所有变量(甚至它们不需要的)
  • 缓存无效粗糙(根 .env 变更使所有无效)
  • 安全风险:包可能意外访问敏感变量
  • 坏习惯从小开始 — 起始模板应建模正确模式

如果必须共享变量,使用 globalEnv 明确什么是共享的,并记录原因。

严格模式过滤 CI 变量

默认情况下,Turborepo 过滤环境变量到仅 env/globalEnv 中的那些。CI 变量可能缺失:

// 如果 CI 脚本需要 GITHUB_TOKEN 但不在 env 中:
{
  "globalPassThroughEnv": ["GITHUB_TOKEN", "CI"],
  "tasks": { ... }
}

或使用 --env-mode=loose(不推荐用于生产)。

应用中的共享代码(应为包)

// 错误:应用中的共享代码
apps/
  web/
    shared/          # 这破坏 monorepo 原则!
      utils.ts

// 正确:提取到包
packages/
  utils/
    src/utils.ts

访问跨包边界的文件

// 错误:深入另一个包的内部
import { Button } from "../../packages/ui/src/button";

// 正确:正确安装和导入
import { Button } from "@repo/ui/button";

太多根依赖项

// 错误:根中的应用依赖项
{
  "dependencies": {
    "react": "^18",
    "next": "^14"
  }
}

// 正确:根中仅仓库工具
{
  "devDependencies": {
    "turbo": "latest"
  }
}

常见任务配置

标准构建管道

{
  "$schema": "https://turborepo.dev/schema.v2.json",
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**", ".next/**", "!.next/cache/**"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

添加 transit 任务如果您有需要并行执行和缓存无效的任务(见下文)。

^dev 模式的开发任务(用于 turbo watch

根 turbo.json 中带 dependsOn: ["^dev"]persistent: falsedev 任务可能看起来不寻常,但对于 turbo watch 工作流是正确的

// 根 turbo.json
{
  "tasks": {
    "dev": {
      "dependsOn": ["^dev"],
      "cache": false,
      "persistent": false  // 包有一次性开发脚本
    }
  }
}

// 包 turbo.json(apps/web/turbo.json)
{
  "extends": ["//"],
  "tasks": {
    "dev": {
      "persistent": true  // 应用运行长运行开发服务器
    }
  }
}

为什么这有效:

  • (例如,@acme/db, @acme/validators)有 "dev": "tsc" — 一次性类型生成,快速完成
  • 应用覆盖 persistent: true 用于实际开发服务器(Next.js 等)
  • turbo watch 在源文件变更时重新运行一次性包 dev 脚本,保持类型同步

预期用法: 运行 turbo watch dev(不是 turbo run dev)。监视模式在文件变更时重新执行一次性任务,同时保持持久任务运行。

替代模式: 使用单独的任务名称如 preparegenerate 用于一次性依赖构建,以使意图更清晰:

{
  "tasks": {
    "prepare": {
      "dependsOn": ["^prepare"],
      "outputs": ["dist/**"]
    },
    "dev": {
      "dependsOn": ["prepare"],
      "cache": false,
      "persistent": true
    }
  }
}

Transit Nodes 用于带缓存无效的并行任务

有些任务可以并行运行(不需要依赖项的构建输出),但必须在依赖源代码变更时使缓存无效。

dependsOn: ["^taskname"] 的问题:

  • 强制顺序执行(慢)

dependsOn: [](无依赖)的问题:

  • 允许并行执行(快)
  • 但缓存不正确 — 变更依赖源代码不会使缓存无效

Transit Nodes 解决两者:

{
  "tasks": {
    "transit": { "dependsOn": ["^transit"] },
    "my-task": { "dependsOn": ["transit"] }
  }
}

transit 任务创建依赖关系而不匹配任何实际脚本,因此任务以正确缓存无效并行运行。

如何识别需要此模式的任务: 寻找读取依赖源文件但不需要其构建输出的任务。

带环境变量

{
  "globalEnv": ["NODE_ENV"],
  "globalDependencies": [".env"],
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**"],
      "env": ["API_URL", "DATABASE_URL"]
    }
  }
}

何时加载参考

加载 references/configuration/ 当:

  • RULE.md:需要 turbo.json 结构概述
  • tasks.md:定义任务配置(dependsOn, outputs, inputs, env, cache)
  • global-options.md:设置 globalEnv, globalDependencies, cacheDir, daemon
  • gotchas.md:遇到意外配置行为

加载 references/caching/ 当:

  • RULE.md:理解缓存哈希如何工作
  • remote-cache.md:设置 Vercel 远程缓存或自托管缓存
  • gotchas.md:调试缓存未命中或使用 --summarize/–dry 标志

加载 references/environment/ 当:

  • RULE.md:配置环境变量(env, globalEnv, passThroughEnv)
  • modes.md:选择严格对比宽松模式,框架推断
  • gotchas.md:故障排除 .env 文件或 CI 环境问题

加载 references/filtering/ 当:

  • RULE.md:需要 --filter 语法概述
  • patterns.md:构建复杂过滤模式以选择性运行

加载 references/ci/ 当:

加载 references/cli/ 当:

  • RULE.md:基本 turbo run 命令用法
  • commands.md:完整 CLI 参考包括 turbo-ignore 和标志

加载 references/best-practices/ 当:

  • RULE.md:Monorepo 结构和组织概述
  • structure.md:仓库布局,工作区配置,TypeScript/ESLint 设置
  • packages.md:创建内部包,JIT 对比编译策略,导出
  • dependencies.md:依赖管理模式,版本同步

加载 references/watch/ 当:

  • RULE.md:设置 turbo watch 用于开发工作流

加载 references/boundaries/ 当:

  • RULE.md:使用实验性边界功能强制包隔离

参考索引

配置

文件 目的
configuration/RULE.md turbo.json 概述,包配置
configuration/tasks.md dependsOn, outputs, inputs, env, cache, persistent
configuration/global-options.md globalEnv, globalDependencies, cacheDir, daemon, envMode
configuration/gotchas.md 常见配置错误

缓存

文件 目的
caching/RULE.md 缓存如何工作,哈希输入
caching/remote-cache.md Vercel 远程缓存,自托管,登录/链接
caching/gotchas.md 调试缓存未命中,–summarize, --dry

环境变量

文件 目的
environment/RULE.md env, globalEnv, passThroughEnv
environment/modes.md 严格对比宽松模式,框架推断
environment/gotchas.md .env 文件,CI 问题

过滤

文件 目的
filtering/RULE.md –filter 语法概述
filtering/patterns.md 常见过滤模式

CI/CD

文件 Purpose
ci/RULE.md 一般 CI 原则
ci/github-actions.md 完整 GitHub Actions 设置
ci/vercel.md Vercel 部署,turbo-ignore
ci/patterns.md –affected, 缓存策略

CLI

文件 目的
cli/RULE.md turbo run 基础
cli/commands.md turbo run 标志,turbo-ignore,其他命令

最佳实践

文件 目的
best-practices/RULE.md Monorepo 最佳实践概述
best-practices/structure.md 仓库结构,工作区配置,TypeScript/ESLint 设置
best-practices/packages.md 创建内部包,JIT 对比编译,导出
best-practices/dependencies.md 依赖管理,安装,版本同步

监视模式

文件 目的
watch/RULE.md turbo watch,可中断任务,开发工作流

边界(实验性)

文件 目的
boundaries/RULE.md 强制包隔离,基于标签的依赖规则

源文档

此技能基于 Turborepo 官方文档: