主题
Turborepo
Turborepo 是面向 Monorepo 的构建任务编排与缓存工具。
它本身不负责安装依赖或管理包版本,而是建立在 pnpm、npm、Yarn 等包管理器提供的 Workspace 能力之上,统一调度多个 package 中的 build、lint、test、typecheck、dev 等任务。
为什么需要 Turborepo
在一个包含多个应用和共享包的仓库中,例如:
bash
apps/
web
admin
api
packages/
ui
utils
config每个应用或包通常都有各自的 package.json 和脚本。Turborepo 可以根据这些包之间的依赖关系,自动决定任务执行顺序,并尽量只执行真正受改动影响的任务。
pnpm Workspace 的职责
pnpm Workspace 主要负责包与依赖管理:
- 统一安装和管理仓库内的依赖。
- 将多个子项目识别为同一个 Workspace。
- 支持通过
workspace:*引用仓库内的本地包。 - 自动建立本地 package 之间的软链接。
- 统一执行 workspace 范围内的脚本。
例如,apps/web 依赖 packages/ui:
json
{
"dependencies": {
"@repo/ui": "workspace:*"
}
}pnpm 会将 @repo/ui 链接到本地的 packages/ui,应用可以像使用普通 npm 包一样使用仓库内部的共享组件或工具库。
Turborepo 的职责
Turborepo 主要解决“任务如何执行”的问题:
- 根据 package 依赖关系安排任务顺序。
- 自动并行执行互不依赖的任务。
- 仅执行受当前改动影响的任务。
- 缓存任务结果,避免重复构建。
- 支持团队共享远程缓存。
- 为 CI 提供更快、更稳定的构建流程。
例如,apps/web 依赖 packages/ui。执行:
bash
pnpm turbo run buildTurborepo 会先构建 packages/ui,再构建 apps/web。
如果 packages/ui 没有变化,并且此前的构建结果仍然有效,Turborepo 可以直接命中缓存,跳过重新构建。
安装与初始化
在已有 pnpm Workspace 中安装 Turborepo:
bash
pnpm -w add -D turbo在根目录 package.json 中添加仓库级脚本:
json
{
"scripts": {
"dev": "turbo dev",
"build": "turbo build",
"lint": "turbo lint",
"test": "turbo test",
"typecheck": "turbo typecheck"
}
}子包需要各自声明对应脚本。Turborepo 只负责任务编排,不会自动生成 build、lint、test 等脚本。
json
{
"name": "@repo/web",
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint .",
"typecheck": "vue-tsc --noEmit"
}
}然后在根目录创建 turbo.json,声明任务依赖、缓存产物和开发任务行为。
turbo.json
Turborepo 通常通过根目录的 turbo.json 描述任务规则:
json
{
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"]
},
"lint": {
"dependsOn": ["^lint"]
},
"test": {
"dependsOn": ["^build"],
"outputs": ["coverage/**"]
},
"dev": {
"cache": false,
"persistent": true
}
}
}字段说明:
dependsOn: ["^build"]:当前 package 执行build前,需要先完成依赖包的build。outputs:声明任务生成的产物目录,Turborepo 会将这些产物纳入缓存。cache: false:不缓存该任务,通常用于本地开发服务。persistent: true:任务会持续运行,例如 Vite、Next.js 或 Node 开发服务器。
缓存机制
Turborepo 会根据任务相关信息生成缓存键,通常包括:
- 当前 package 的源码文件。
package.json与锁文件。- 环境变量。
- 任务命令。
turbo.json配置。- 依赖 package 的构建结果。
只要这些输入没有变化,Turborepo 就可以复用之前的任务结果。
第一次执行:
bash
pnpm turbo run build会正常构建所有需要构建的 package。
第二次在代码未变化的情况下执行相同命令时,Turborepo 可以直接从本地缓存恢复构建产物,通常明显快于重新构建。
本地缓存与远程缓存
默认情况下,Turborepo 使用本地缓存,缓存通常保存在仓库中的 .turbo 目录。
多人协作或 CI 场景可以启用远程缓存。某位开发者或 CI 已经完成过的构建结果,其他开发者或后续 CI 任务可以直接复用,无需再次执行相同构建。
远程缓存适合以下场景:
- 多人维护同一个 Monorepo。
- GitHub Actions、GitLab CI 等持续集成环境。
- 应用较多、构建时间较长。
- 频繁执行
build、lint、test、typecheck。
与 pnpm Workspace 的关系
| 工具 | 主要职责 |
|---|---|
| pnpm Workspace | 管理 package、依赖安装、本地包链接、Workspace 范围脚本执行 |
| Turborepo | 编排任务依赖、并行执行、增量执行、本地缓存、远程缓存 |
可以理解为:
- pnpm Workspace 解决“仓库中有哪些包,以及这些包如何互相依赖”。
- Turborepo 解决“这些包的构建、检查、测试任务应该以什么顺序、什么范围、高效地执行”。
因此,常见组合是:
bash
pnpm Workspace + Turborepopnpm 负责包管理,Turborepo 负责任务调度与构建加速。两者并不冲突,而是互补关系。
