Turborepo构建系统技能Skill turborepo

Turborepo 是一个针对 JavaScript 和 TypeScript monorepos 的高性能构建系统,用于加速开发工作流程。它提供智能缓存、任务编排和远程执行功能,适用于设置和管理多包存储库。关键词包括:构建系统、monorepo、缓存、任务编排、JavaScript、TypeScript、DevOps、CI/CD、高性能构建、远程缓存。

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

名称: turborepo 描述: 实施 Turborepo 的指南 - 一个针对 JavaScript 和 TypeScript monorepos 的高性能构建系统。在设置 monorepos、优化构建性能、实施任务管道、配置缓存策略或跨多个包编排任务时使用。 许可证: MIT 版本: 1.0.0

Turborepo 技能

Turborepo 是一个针对 JavaScript 和 TypeScript monorepos 优化的高性能构建系统,使用 Rust 编写。它提供智能缓存、任务编排和远程执行功能,以显著加速开发工作流程。

参考

https://turborepo.com/llms.txt

何时使用此技能

在以下情况下使用此技能:

  • 设置具有多个包的新 monorepo
  • 优化现有 monorepos 中的构建性能
  • 跨包实施任务管道
  • 配置智能缓存策略
  • 为团队设置远程缓存
  • 编排具有依赖感知的任务
  • 将 monorepo 与 CI/CD 管道集成
  • 从 Lerna、Nx 或其他 monorepo 工具迁移
  • 构建微前端或共享库
  • 管理工作区依赖

核心概念

1. Monorepo 架构

Turborepo 将代码组织到单个存储库中的包内:

  • 根包: 包含工作区配置
  • 内部包: 共享库、实用工具、配置
  • 应用程序: 前端应用、后端服务等
  • 工作区: npm/yarn/pnpm 工作区配置

2. 任务管道

任务在依赖图中组织:

  • 任务依赖: 定义执行顺序(构建先于测试)
  • 包依赖: 尊重内部包关系
  • 并行执行: 同时运行独立任务
  • 拓扑排序: 按正确依赖顺序执行任务

3. 智能缓存

Turborepo 根据输入缓存任务输出:

  • 本地缓存: 在本地机器上存储输出
  • 远程缓存: 跨团队/CI 共享缓存(Vercel 或自定义)
  • 基于内容的哈希: 仅当输入更改时重新运行
  • 缓存恢复: 从缓存中即时完成任务

4. 任务输出

定义缓存内容:

  • 构建产物 (dist/, build/)
  • 测试结果
  • 生成的文件
  • 类型定义

安装

先决条件

# 需要 Node.js 18+ 和包管理器
node --version  # v18.0.0+

全局安装

# npm
npm install turbo --global

# yarn
yarn global add turbo

# pnpm
pnpm add turbo --global

# bun
bun add turbo --global

按项目安装

# npm
npm install turbo --save-dev

# yarn
yarn add turbo --dev

# pnpm
pnpm add turbo --save-dev

# bun
bun add turbo --dev

项目设置

创建新 Monorepo

使用官方示例:

npx create-turbo@latest

交互式提示将询问:

  • 项目名称
  • 包管理器 (npm/yarn/pnpm/bun)
  • 示例模板选择

手动设置

1. 初始化工作区:

// package.json (根)
{
  "name": "my-turborepo",
  "private": true,
  "workspaces": ["apps/*", "packages/*"],
  "scripts": {
    "build": "turbo run build",
    "dev": "turbo run dev",
    "test": "turbo run test",
    "lint": "turbo run lint"
  },
  "devDependencies": {
    "turbo": "latest"
  }
}

2. 创建目录结构:

my-turborepo/
├── apps/
│   ├── web/              # Next.js 应用
│   └── docs/             # 文档站点
├── packages/
│   ├── ui/               # 共享 UI 组件
│   ├── config/           # 共享配置 (ESLint, TS)
│   └── tsconfig/         # 共享 TypeScript 配置
├── turbo.json            # Turborepo 配置
└── package.json          # 根 package.json

3. 创建 turbo.json:

{
  "$schema": "https://turbo.build/schema.json",
  "globalDependencies": ["**/.env.*local"],
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "!.next/cache/**", "dist/**"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    },
    "lint": {},
    "test": {
      "dependsOn": ["build"]
    }
  }
}

配置 (turbo.json)

基本结构

{
  "$schema": "https://turbo.build/schema.json",
  "globalDependencies": [".env", "tsconfig.json"],
  "globalEnv": ["NODE_ENV"],
  "pipeline": {
    // 任务定义
  }
}

管道配置

带依赖的任务:

{
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**", ".next/**"],
      "env": ["NODE_ENV", "API_URL"]
    }
  }
}

关键属性:

  • dependsOn: 先运行的任务
    • ["^build"]: 先运行依赖项的构建
    • ["build"]: 先运行自身构建
    • ["^build", "lint"]: 运行依赖项构建和自身 lint
  • outputs: 缓存的文件/目录
  • inputs: 覆盖输入检测(默认:所有跟踪文件)
  • cache: 启用/禁用缓存(默认:true)
  • env: 影响输出的环境变量
  • persistent: 保持任务运行(用于开发服务器)
  • outputMode: 控制输出显示

任务依赖模式

拓扑 (^):

{
  "build": {
    "dependsOn": ["^build"]  // 先运行依赖项的构建
  }
}

常规:

{
  "deploy": {
    "dependsOn": ["build", "test"]  // 先运行自身构建和测试
  }
}

组合:

{
  "test": {
    "dependsOn": ["^build", "lint"]  // 依赖项构建,然后自身 lint
  }
}

输出模式

{
  "pipeline": {
    "build": {
      "outputMode": "full"        // 显示所有输出
    },
    "dev": {
      "outputMode": "hash-only"   // 仅显示缓存哈希
    },
    "test": {
      "outputMode": "new-only"    // 仅显示新输出
    },
    "lint": {
      "outputMode": "errors-only" // 仅显示错误
    }
  }
}

环境变量

全局环境变量:

{
  "globalEnv": ["NODE_ENV", "CI"],
  "globalDependencies": [".env", ".env.local"]
}

每任务环境变量:

{
  "pipeline": {
    "build": {
      "env": ["NEXT_PUBLIC_API_URL", "DATABASE_URL"],
      "passThroughEnv": ["CUSTOM_VAR"]  // 传递而不哈希
    }
  }
}

命令

turbo run

跨包运行任务:

# 在所有包中运行构建
turbo run build

# 运行多个任务
turbo run build test lint

# 在特定包中运行
turbo run build --filter=web
turbo run build --filter=@myorg/ui

# 在匹配模式的包中运行
turbo run build --filter='./apps/*'

# 强制执行(跳过缓存)
turbo run build --force

# 从特定目录运行
turbo run build --filter='[./apps/web]'

# 运行带依赖
turbo run build --filter='...^web'

# 并行执行控制
turbo run build --concurrency=3
turbo run build --concurrency=50%

# 出错继续
turbo run test --continue

# 干运行
turbo run build --dry-run

# 输出控制
turbo run build --output-logs=new-only
turbo run build --output-logs=hash-only
turbo run build --output-logs=errors-only
turbo run build --output-logs=full

turbo prune

创建 monorepo 的子集:

# 修剪特定应用
turbo prune --scope=web

# 带 Docker 修剪
turbo prune --scope=api --docker

# 输出到自定义目录
turbo prune --scope=web --out-dir=./deploy

使用场景:

  • Docker 构建(仅包括必要包)
  • 部署特定应用
  • 减少 CI/CD 上下文大小

turbo gen

在 monorepo 中生成代码:

# 生成新包
turbo gen workspace

# 从自定义生成器生成
turbo gen my-generator

# 列出可用生成器
turbo gen --list

turbo link

将本地存储库链接到远程缓存:

# 链接到 Vercel
turbo link

# 取消链接
turbo unlink

turbo login

使用 Vercel 认证:

turbo login

turbo ls

列出 monorepo 中的包:

# 列出所有包
turbo ls

# JSON 输出
turbo ls --json

过滤

按包名过滤

# 单个包
turbo run build --filter=web

# 多个包
turbo run build --filter=web --filter=api

# 作用域包
turbo run build --filter=@myorg/ui

按模式过滤

# 所有应用
turbo run build --filter='./apps/*'

# 模式匹配
turbo run build --filter='*-ui'

按目录过滤

# 从特定目录
turbo run build --filter='[./apps/web]'

按 Git 过滤

# 自 main 后更改
turbo run build --filter='[main]'

# 自 HEAD~1 后更改
turbo run build --filter='[HEAD~1]'

# 工作目录中更改
turbo run test --filter='...[HEAD]'

按依赖过滤

# 包及其依赖
turbo run build --filter='...web'

# 包的依赖仅
turbo run build --filter='...^web'

# 包及其依赖项
turbo run test --filter='ui...'

# 包的依赖项仅
turbo run test --filter='^ui...'

缓存策略

本地缓存

默认启用,存储在 ./node_modules/.cache/turbo

缓存行为:

{
  "pipeline": {
    "build": {
      "outputs": ["dist/**"],  // 缓存 dist 目录
      "cache": true            // 启用缓存(默认)
    },
    "dev": {
      "cache": false           // 为开发服务器禁用
    }
  }
}

清除缓存:

# 清除 Turbo 缓存
rm -rf ./node_modules/.cache/turbo

# 或使用 turbo 命令
turbo run build --force  # 跳过此运行的缓存

远程缓存

跨团队和 CI 共享缓存:

1. 链接到 Vercel(推荐):

turbo login
turbo link

2. 自定义远程缓存:

// .turbo/config.json
{
  "teamid": "team_123",
  "apiurl": "https://cache.example.com",
  "token": "your-token"
}

优势:

  • 跨团队共享构建
  • 加速 CI/CD
  • 一致的构建
  • 减少计算成本

缓存签名

缓存失效时:

  • 源文件更改
  • 依赖更改
  • 环境变量更改(如指定)
  • 全局依赖更改
  • 任务配置更改

控制输入:

{
  "pipeline": {
    "build": {
      "inputs": ["src/**/*.ts", "!src/**/*.test.ts"],
      "env": ["NODE_ENV"]
    }
  }
}

工作区模式

包类型

1. 内部包 (packages/*):

// packages/ui/package.json
{
  "name": "@myorg/ui",
  "version": "0.0.0",
  "main": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "scripts": {
    "build": "tsc",
    "dev": "tsc --watch",
    "lint": "eslint ."
  }
}

2. 应用 (apps/*):

// apps/web/package.json
{
  "name": "web",
  "version": "1.0.0",
  "private": true,
  "dependencies": {
    "@myorg/ui": "*",
    "next": "latest"
  },
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  }
}

依赖管理

工作区协议 (pnpm/yarn):

{
  "dependencies": {
    "@myorg/ui": "workspace:*"
  }
}

版本协议 (npm):

{
  "dependencies": {
    "@myorg/ui": "*"
  }
}

共享配置

ESLint 配置包:

// packages/eslint-config/index.js
module.exports = {
  extends: ["next", "prettier"],
  rules: {
    // 共享规则
  }
}

TypeScript 配置包:

// packages/tsconfig/base.json
{
  "compilerOptions": {
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  }
}

使用:

// apps/web/tsconfig.json
{
  "extends": "@myorg/tsconfig/base.json",
  "compilerOptions": {
    "jsx": "preserve"
  }
}

CI/CD 集成

GitHub Actions

name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 18

      - name: 安装依赖
        run: npm install

      - name: 构建
        run: npx turbo run build
        env:
          TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
          TURBO_TEAM: ${{ secrets.TURBO_TEAM }}

      - name: 测试
        run: npx turbo run test

GitLab CI

image: node:18

cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - node_modules/
    - .turbo/

build:
  stage: build
  script:
    - npm install
    - npx turbo run build
  variables:
    TURBO_TOKEN: $TURBO_TOKEN
    TURBO_TEAM: $TURBO_TEAM

Docker

FROM node:18-alpine AS base

# 修剪工作区
FROM base AS builder
RUN npm install -g turbo
COPY . .
RUN turbo prune --scope=web --docker

# 安装依赖
FROM base AS installer
COPY --from=builder /app/out/json/ .
COPY --from=builder /app/out/package-lock.json ./package-lock.json
RUN npm install

# 构建
COPY --from=builder /app/out/full/ .
RUN npx turbo run build --filter=web

# 运行器
FROM base AS runner
COPY --from=installer /app/apps/web/.next/standalone ./
COPY --from=installer /app/apps/web/.next/static ./apps/web/.next/static
COPY --from=installer /app/apps/web/public ./apps/web/public

CMD node apps/web/server.js

优化提示

  1. 在 CI 中使用远程缓存:
env:
  TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
  TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
  1. 缓存 node_modules:
- uses: actions/cache@v3
  with:
    path: node_modules
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
  1. 仅运行受影响任务:
turbo run build test --filter='...[origin/main]'

框架集成

Next.js

// apps/web/package.json
{
  "name": "web",
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "next": "latest",
    "react": "latest"
  }
}

turbo.json:

{
  "pipeline": {
    "build": {
      "outputs": [".next/**", "!.next/cache/**"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

Vite

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

NuxtJS

{
  "pipeline": {
    "build": {
      "outputs": [".output/**", ".nuxt/**"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

开发工具集成

TypeScript

{
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**", "*.tsbuildinfo"]
    },
    "typecheck": {
      "dependsOn": ["^build"]
    }
  }
}

ESLint

{
  "pipeline": {
    "lint": {
      "dependsOn": ["^build"],
      "outputs": []
    }
  }
}

Jest / Vitest

{
  "pipeline": {
    "test": {
      "dependsOn": ["build"],
      "outputs": ["coverage/**"],
      "cache": true
    }
  }
}

Prisma

{
  "pipeline": {
    "db:generate": {
      "cache": false
    },
    "db:push": {
      "cache": false
    }
  }
}

最佳实践

1. 结构化您的 Monorepo

my-monorepo/
├── apps/                    # 应用
│   ├── web/                # 前端应用
│   ├── api/                # 后端 API
│   └── docs/               # 文档
├── packages/               # 共享包
│   ├── ui/                 # UI 组件
│   ├── config/             # 共享配置
│   ├── utils/              # 实用工具
│   └── tsconfig/           # TS 配置
├── tooling/                # 开发工具
│   ├── eslint-config/
│   └── prettier-config/
└── turbo.json

2. 定义清晰的任务依赖

{
  "pipeline": {
    "build": {
      "dependsOn": ["^build"]
    },
    "test": {
      "dependsOn": ["build"]
    },
    "lint": {
      "dependsOn": ["^build"]
    },
    "deploy": {
      "dependsOn": ["build", "test", "lint"]
    }
  }
}

3. 优化缓存配置

  • 缓存构建输出,而非源文件
  • 在输出中包含所有生成的文件
  • 排除缓存目录(例如,.next/cache
  • 为开发服务器禁用缓存
{
  "pipeline": {
    "build": {
      "outputs": [
        "dist/**",
        ".next/**",
        "!.next/cache/**",
        "storybook-static/**"
      ]
    },
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

4. 明智使用环境变量

{
  "globalEnv": ["NODE_ENV", "CI"],
  "pipeline": {
    "build": {
      "env": ["NEXT_PUBLIC_API_URL"],
      "passThroughEnv": ["DEBUG"]  // 不影响缓存
    }
  }
}

5. 利用远程缓存

  • 为所有团队成员启用
  • 在 CI/CD 中配置
  • 显著减少构建时间
  • 对大团队特别有益

6. 有效使用过滤器

# 仅构建更改的包
turbo run build --filter='...[origin/main]'

# 构建特定应用及其依赖
turbo run build --filter='...web'

# 仅测试受影响的包
turbo run test --filter='...[HEAD^1]'

7. 一致组织脚本

根 package.json:

{
  "scripts": {
    "build": "turbo run build",
    "dev": "turbo run dev",
    "lint": "turbo run lint",
    "test": "turbo run test",
    "clean": "turbo run clean && rm -rf node_modules"
  }
}

8. 处理持续任务

{
  "pipeline": {
    "dev": {
      "cache": false,
      "persistent": true  // 保持运行
    }
  }
}

常见模式

全栈应用

apps/
├── web/          # Next.js 前端
│   └── package.json
├── api/          # Express 后端
│   └── package.json
└── mobile/       # React Native
    └── package.json

packages/
├── ui/           # 共享 UI 组件
├── database/     # 数据库客户端/迁移
├── types/        # 共享 TypeScript 类型
└── config/       # 共享配置

共享组件库

packages/
├── ui/                    # 组件库
│   ├── src/
│   ├── package.json
│   └── tsconfig.json
└── ui-docs/              # Storybook
    ├── .storybook/
    ├── stories/
    └── package.json

微前端

apps/
├── shell/        # 容器应用
├── dashboard/    # 仪表板 MFE
└── settings/     # 设置 MFE

packages/
├── shared-ui/    # 共享组件
└── router/       # 路由逻辑

故障排除

缓存问题

问题: 任务应使用缓存时未使用

# 检查导致缓存未命中的原因
turbo run build --dry-run=json

# 强制重建
turbo run build --force

# 清除缓存
rm -rf ./node_modules/.cache/turbo

问题: 缓存太大

# 在 turbo.json 中限制缓存大小
{
  "cacheDir": ".turbo",
  "cacheSize": "50gb"
}

依赖问题

问题: 找不到内部包

# 确保工作区设置正确
npm install

# 检查包名称匹配
npm ls @myorg/ui

# 重新构建依赖
turbo run build --filter='...web'

任务执行问题

问题: 任务运行顺序错误

  • 检查 dependsOn 配置
  • 使用 ^task 表示依赖任务
  • 验证任务名称与 package.json 脚本匹配

问题: 开发服务器未启动

{
  "pipeline": {
    "dev": {
      "cache": false,
      "persistent": true  // 添加此项
    }
  }
}

性能问题

问题: 构建耗时过长

# 使用并发限制运行
turbo run build --concurrency=2

# 使用过滤器减少构建
turbo run build --filter='...[origin/main]'

# 检查不必要的依赖
turbo run build --dry-run

问题: 远程缓存无效

# 验证认证
turbo link

# 检查环境变量
echo $TURBO_TOKEN
echo $TURBO_TEAM

# 测试连接
turbo run build --output-logs=hash-only

迁移指南

从 Lerna

  1. 用 Turborepo 替换 Lerna:
npm uninstall lerna
npm install turbo --save-dev
  1. 将 lerna.json 转换为 turbo.json:
{
  "pipeline": {
    "build": {
      "dependsOn": ["^build"]
    }
  }
}
  1. 更新脚本:
{
  "scripts": {
    "build": "turbo run build",
    "test": "turbo run test"
  }
}

从 Nx

  1. 安装 Turborepo:
npm install turbo --save-dev
  1. 将 nx.json 转换为 turbo.json:
  • 将 targetDefaults 映射到 pipeline
  • 转换 dependsOn 语法
  • 配置缓存
  1. 更新工作区配置
  2. 迁移 CI/CD 脚本

资源

实施清单

设置 Turborepo 时:

  • [ ] 全局或按项目安装 Turborepo
  • [ ] 设置工作区结构 (apps/, packages/)
  • [ ] 创建 turbo.json 带管道配置
  • [ ] 定义任务依赖 (build, test, lint)
  • [ ] 为每个任务配置缓存输出
  • [ ] 设置全局依赖和环境变量
  • [ ] 链接到远程缓存 (Vercel 或自定义)
  • [ ] 配置 CI/CD 集成
  • [ ] 为大型存储库添加过滤策略
  • [ ] 为团队记录 monorepo 结构
  • [ ] 设置代码生成 (turbo gen)
  • [ ] 配置带 turbo prune 的 Docker 构建
  • [ ] 本地测试缓存行为
  • [ ] 在 CI 中验证远程缓存
  • [ ] 优化并发设置