简介
Turborepo = 给 monorepo 用的“智能任务调度器 + 缓存引擎”
为什么会需要 Turborepo
传统 monorepo 的痛点,假设你有如下目录:
packages/
utils
ui
apps/
admin
docs
依赖关系:
admin -> ui -> utils
docs -> ui
没 turbo 时,常见做法
pnpm -r dev
pnpm -r build
问题来了:
- ❌ 不关心依赖顺序,执行
build或dev命令执行顺序不保证符合包依赖顺序,过去的解决方式"build": "pnpm --filter utils build && pnpm --filter ui build && pnpm --filter admin build" - ❌ 改一个 utils,全部 app 都 build
- ❌ 每次 CI 都从 0 开始
- ❌ 项目一大,命令慢到崩溃
Turborepo 到底解决了什么
- 按依赖图调度任务(核心能力)
Turborepo 会分析:package.json 里的依赖关系、workspace 结构,然后自动得到一张图:
utils
↓
ui
↓
admin / docs
执行turbo run build后:
- 先 build utils
- 再 build ui
- 最后 build admin / docs
- 能并行的并行,不能的就等
- 不用你手动维护顺序
缓存机制
当你跑过一次turbo run build
下次:
- 源码没变
- 依赖没变
- 输出目录没变
👉 直接跳过,秒完成
CI / 团队缓存(进阶)
- A 同事 build 过
- B 同事拉代码再 build,直接命中缓存
只跑“受影响”的包
你只改了 packages/utils 时,再执行 turbo run build
结果是:
- ✅ utils
- ✅ ui(依赖 utils)
- ✅ admin / docs
- ❌ 其他无关包不会跑
pnpm -r:全部跑
turbo:最小集合
dev 场景
它会:
- 启动所有有
dev脚本的包 - 按依赖顺序
- 并行拉起
- 支持长期运行(vite dev server)
Turborepo 使用
- 安装 turbo
pnpm add -D turbo
- 新增 turbo.json
{
// 给编辑器 / IDE 用的,提供智能提示、校验,不影响运行
"$schema": "https://turbo.build/schema.json",
// 这些文件一旦改动,整个 turbo 缓存全部失效
"globalDependencies": [
// 依赖变了,构建产物一定可能变,必须让缓存失效
"pnpm-lock.yaml",
// 本地环境变量,会影响 dev / build 行为,防止你“改了环境却命中旧缓存”
"**/.env.*local",
// 编译目标,path alias,strict 规则,改一次,所有包都该重跑
"**/tsconfig*.json",
"internal/node-utils/*.json",
"internal/node-utils/src/**/*.ts",
// Tailwind 主题
"internal/tailwind-config/src/**/*.ts",
// Vite 通用配置
"internal/vite-config/*.json",
"internal/vite-config/src/**/*.ts",
"scripts/*/src/**/*.ts",
"scripts/*/src/**/*.json"
],
// NODE_ENV 变化 → 所有任务缓存失效,防止你用 dev 的缓存跑 prod 构建
"globalEnv": ["NODE_ENV"],
// 调度规则
"tasks": {
"build": {
// 所有依赖包先 build
"dependsOn": ["^build"],
// 构建产物,turbo 用它们来:判断是否可缓存、判断是否命中缓存
"outputs": [
// 普通前端:`dist/**`
"dist/**",
// 打包产物:`dist.zip`
"dist.zip",
// 文档站:`.vitepress/dist`
".vitepress/dist.zip",
".vitepress/dist/**"
]
},
"preview": {
// preview 必须在 build 之后
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"build:analyze": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"@vben/backend-mock#build": {
"dependsOn": ["^build"],
"outputs": [".nitro/**", ".output/**"]
},
"test:e2e": {},
"dev": {
// 不依赖 build(dev 自己处理)
"dependsOn": [],
"outputs": [],
// 不缓存(dev server 没意义)
"cache": false,
// vite / node server 不会被当成“已完成”
"persistent": true
},
"typecheck": {
"outputs": []
}
}
}