mcpField
T
turborepo

turborepo

github.com/timelessco开发51 次安装
代码仓库

关于 turborepo

这是一项介绍如何用 Turborepo 构建和管理 JavaScript、TypeScript 单体仓库的技能,涵盖任务编排、缓存、工作区配置与 CI 流程,适合维护多包仓库的开发者。

主要功能

  1. 01配置依赖感知的任务流水线
  2. 02使用本地与远程缓存
  3. 03按包或变更筛选任务
  4. 04精简部署所需的工作区
  5. 05设置工作区包

适用场景

  1. 01加快重复的单体仓库构建
  2. 02仅对变更包运行 CI 任务
  3. 03准备应用专用的 Docker 构建输入
  4. 04协调构建、测试与 lint 任务

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/timelessco/recollect --skill turborepo

安装后在 Claude Code 中输入/turborepo确认已加载。

详细介绍

Turborepo 技能

Turborepo 是一款高性能构建系统,针对 JavaScript 和 TypeScript 单体仓库进行了优化,使用 Rust 编写。它提供智能缓存、任务编排和远程执行功能,可大幅加快开发工作流。

参考

https://turborepo.com/llms.txt

何时使用此技能

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

  • 使用多个包搭建新的单体仓库
  • 优化现有单体仓库的构建性能
  • 实现跨包的任务流水线
  • 配置智能缓存策略
  • 为团队设置远程缓存
  • 根据依赖关系编排任务
  • 将单体仓库集成到 CI/CD 流水线中
  • 从 Lerna、Nx 或其他单体仓库工具迁移
  • 构建微前端或共享库
  • 管理工作区依赖

核心概念

1. 单体仓库架构

Turborepo 将代码组织到单个仓库内的多个包中:

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

任务按依赖关系图组织:

  • 任务依赖:定义执行顺序(先构建,再测试)
  • 包依赖:遵循内部包之间的关系
  • 并行执行:同时运行互不依赖的任务
  • 拓扑排序:按正确的依赖顺序执行任务
3. 智能缓存

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

  • 本地缓存:在本地计算机上存储输出
  • 远程缓存:在团队和 CI 之间共享缓存(Vercel 或自定义方案)
  • 基于内容的哈希:仅在输入变更时重新运行
  • 缓存恢复:从缓存中即时完成任务
4. 任务输出

定义要缓存的内容:

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

安装

先决条件
# Requires Node.js 18+ and a package manager
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

项目设置

创建新的单体仓库

使用官方示例:

npx create-turbo@latest

交互式提示会询问:

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

1. 初始化工作区:

// package.json (root)
{
	"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 app
│   └── docs/             # Documentation site
├── packages/
│   ├── ui/               # Shared UI components
│   ├── config/           # Shared configs (ESLint, TS)
│   └── tsconfig/         # Shared TypeScript configs
├── turbo.json            # Turborepo configuration
└── package.json          # Root 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": {
		// Task definitions
	}
}
流水线配置

具有依赖关系的任务:

{
	"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"] // Run dependencies' build first
	}
}

常规:

{
	"deploy": {
		"dependsOn": ["build", "test"] // Run own build and test first
	}
}

组合:

{
	"test": {
		"dependsOn": ["^build", "lint"] // Deps' build, then own lint
	}
}
输出模式
{
	"pipeline": {
		"build": {
			"outputMode": "full" // Show all output
		},
		"dev": {
			"outputMode": "hash-only" // Show cache hash only
		},
		"test": {
			"outputMode": "new-only" // Show new output only
		},
		"lint": {
			"outputMode": "errors-only" // Show errors only
		}
	}
}
环境变量

全局环境变量:

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

单任务环境变量:

{
	"pipeline": {
		"build": {
			"env": ["NEXT_PUBLIC_API_URL", "DATABASE_URL"],
			"passThroughEnv": ["CUSTOM_VAR"] // Pass without hashing
		}
	}
}

命令

turbo run

在各个包中运行任务:

# Run build in all packages
turbo run build

# Run multiple tasks
turbo run build test lint

# Run in specific packages
turbo run build --filter=web
turbo run build --filter=@myorg/ui

# Run in packages matching pattern
turbo run build --filter='./apps/*'

# Force execution (skip cache)
turbo run build --force

# Run from specific directory
turbo run build --filter='[./apps/web]'

# Run with dependencies
turbo run build --filter='...^web'

# Parallel execution control
turbo run build --concurrency=3
turbo run build --concurrency=50%

# Continue on error
turbo run test --continue

# Dry run
turbo run build --dry-run

# Output control
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

创建单体仓库的子集:

# Prune for specific app
turbo prune --scope=web

# Prune with Docker
turbo prune --scope=api --docker

# Output to custom directory
turbo prune --scope=web --out-dir=./deploy

使用场景:

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

在单体仓库中生成代码:

# Generate new package
turbo gen workspace

# Generate from custom generator
turbo gen my-generator

# List available generators
turbo gen --list
turbo link

将本地仓库连接到远程缓存:

# Link to Vercel
turbo link

# Unlink
turbo unlink
turbo login

通过 Vercel 进行身份验证:

turbo login
turbo ls

列出单体仓库中的包:

# List all packages
turbo ls

# JSON output
turbo ls --json

筛选

按包名称筛选
# Single package
turbo run build --filter=web

# Multiple packages
turbo run build --filter=web --filter=api

# Scoped package
turbo run build --filter=@myorg/ui
按模式筛选
# All apps
turbo run build --filter='./apps/*'

# Pattern matching
turbo run build --filter='*-ui'
按目录筛选
# From specific directory
turbo run build --filter='[./apps/web]'
按 Git 筛选
# Changed since main
turbo run build --filter='[main]'

# Changed since HEAD~1
turbo run build --filter='[HEAD~1]'

# Changed in working directory
turbo run test --filter='...[HEAD]'
按依赖项筛选
# Package and its dependencies
turbo run build --filter='...web'

# Package's dependencies only
turbo run build --filter='...^web'

# Package and its dependents
turbo run test --filter='ui...'

# Package's dependents only
turbo run test --filter='^ui...'

缓存策略

本地缓存

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

缓存行为:

{
	"pipeline": {
		"build": {
			"outputs": ["dist/**"], // Cache dist directory
			"cache": true // Enable caching (default)
		},
		"dev": {
			"cache": false // Disable for dev servers
		}
	}
}

清除缓存:

# Clear Turbo cache
rm -rf ./node_modules/.cache/turbo

# Or use turbo command
turbo run build --force # Skip cache for this run
远程缓存

在团队和 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: {
		// shared 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: Install dependencies
        run: npm install

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

      - name: Test
        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

# Prune workspace
FROM base AS builder
RUN npm install -g turbo
COPY . .
RUN turbo prune --scope=web --docker

# Install dependencies
FROM base AS installer
COPY --from=builder /app/out/json/ .
COPY --from=builder /app/out/package-lock.json ./package-lock.json
RUN npm install

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

# Runner
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. 规划单体仓库结构
my-monorepo/
├── apps/                    # Applications
│   ├── web/                # Frontend app
│   ├── api/                # Backend API
│   └── docs/               # Documentation
├── packages/               # Shared packages
│   ├── ui/                 # UI components
│   ├── config/             # Shared configs
│   ├── utils/              # Utilities
│   └── tsconfig/           # TS configs
├── tooling/                # Development tools
│   ├── 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"] // Don't affect cache
		}
	}
}
5. 利用远程缓存
  • 为所有团队成员启用
  • 在 CI/CD 中配置
  • 显著缩短构建时间
  • 对大型团队尤其有益
6. 有效使用筛选器
# Build only changed packages
turbo run build --filter='...[origin/main]'

# Build specific app with dependencies
turbo run build --filter='...web'

# Test only affected packages
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 // Keeps running
		}
	}
}

常见模式

全栈应用
apps/
├── web/          # Next.js frontend
│   └── package.json
├── api/          # Express backend
│   └── package.json
└── mobile/       # React Native
    └── package.json

packages/
├── ui/           # Shared UI components
├── database/     # Database client/migrations
├── types/        # Shared TypeScript types
└── config/       # Shared configs
共享组件库
packages/
├── ui/                    # Component library
│   ├── src/
│   ├── package.json
│   └── tsconfig.json
└── ui-docs/              # Storybook
    ├── .storybook/
    ├── stories/
    └── package.json
微前端
apps/
├── shell/        # Container app
├── dashboard/    # Dashboard MFE
└── settings/     # Settings MFE

packages/
├── shared-ui/    # Shared components
└── router/       # Routing logic

故障排除

缓存问题

问题:任务本应使用缓存却未使用

# Check what's causing cache miss
turbo run build --dry-run=json

# Force rebuild
turbo run build --force

# Clear cache
rm -rf ./node_modules/.cache/turbo

问题:缓存过大

# Limit cache size in turbo.json
{
	"cacheDir": ".turbo",
	"cacheSize": "50gb"
}
依赖问题

问题:找不到内部软件包

# Ensure workspace is set up correctly
npm install

# Check package names match
npm ls @myorg/ui

# Rebuild dependencies
turbo run build --filter='...web'
任务执行问题

问题:任务运行顺序错误

  • 检查 dependsOn 配置
  • 对依赖任务使用 ^task
  • 确认任务名称与 package.json 脚本匹配

问题:开发服务器无法启动

{
	"pipeline": {
		"dev": {
			"cache": false,
			"persistent": true // Add this
		}
	}
}
性能问题

问题:构建耗时过长

# Run with concurrency limit
turbo run build --concurrency=2

# Use filters to build less
turbo run build --filter='...[origin/main]'

# Check for unnecessary dependencies
turbo run build --dry-run

问题:远程缓存无法使用

# Verify authentication
turbo link

# Check environment variables
echo $TURBO_TOKEN
echo $TURBO_TEAM

# Test connection
turbo run build --output-logs=hash-only

迁移指南

从 Lerna 迁移
  1. 将 Lerna 替换为 Turborepo:
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 集成
  • 为大型代码仓库添加筛选策略
  • 为团队编写单体仓库结构文档
  • 设置代码生成(turbo gen)
  • 使用 turbo prune 配置 Docker 构建
  • 在本地测试缓存行为
  • 在 CI 中验证远程缓存
  • 优化并发设置

评论

支持 Markdown