DevToolBox免费
博客

Monorepo工具2026:Turborepo vs Nx vs Lerna vs pnpm Workspaces对比

15 分钟作者 DevToolBox

Monorepo(多包和应用的单一仓库)改善了代码共享、重构和依赖管理。2026 年,三种主流方法是 Turborepo(快速缓存、简单配置)、Nx(强大的生成器和影响检测)和 pnpm 工作区(轻量级,无需额外工具)。

Turborepo:设置和结构

Turborepo 针对 JavaScript/TypeScript monorepo 进行了优化。它使用简单的管道定义和激进的缓存来跳过输入未更改的任务。

# Create a new Turborepo monorepo
npx create-turbo@latest my-monorepo
cd my-monorepo

# Or add Turborepo to an existing monorepo
npm install turbo --save-dev

# Directory structure
my-monorepo/
├── apps/
│   ├── web/          # Next.js app
│   └── docs/         # Docs site
├── packages/
│   ├── ui/           # Shared React components
│   ├── utils/        # Shared utilities
│   └── tsconfig/     # Shared TypeScript configs
├── turbo.json        # Pipeline configuration
└── package.json      # Root workspace config

Turborepo 管道配置

turbo.json 管道定义了任务之间的关系和要缓存的输出。^ 前缀表示"等待依赖包首先构建"。

// turbo.json — pipeline definition
{
    "$schema": "https://turbo.build/schema.json",
    "pipeline": {
        "build": {
            "dependsOn": ["^build"],   // ^ means: run in dependency order
            "outputs": [".next/**", "!.next/cache/**", "dist/**"]
        },
        "test": {
            "dependsOn": ["^build"],
            "inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts"]
        },
        "lint": {
            "outputs": []
        },
        "dev": {
            "cache": false,            // Never cache dev servers
            "persistent": true         // Long-running task
        },
        "type-check": {
            "dependsOn": ["^build"],
            "outputs": []
        }
    },
    "globalEnv": ["NODE_ENV", "DATABASE_URL"]
}

# Run all build tasks (uses cache if inputs unchanged)
npx turbo build

# Run only for specific apps/packages
npx turbo build --filter=web
npx turbo build --filter=...ui  # ui and all its dependents

# Force re-run (bypass cache)
npx turbo build --force

# View task graph
npx turbo build --graph

Nx:设置和项目图

Nx 提供更丰富的功能集:代码生成器、影响命令(仅为更改的代码运行任务),以及对许多框架的一流支持。

# Create Nx monorepo
npx create-nx-workspace@latest my-nx-repo --preset=ts

# Add Nx to existing monorepo
npx nx@latest init

# Generate a new app or library
nx generate @nx/next:app web
nx generate @nx/react:library ui
nx generate @nx/node:library utils

# nx.json — workspace configuration
{
    "tasksRunnerOptions": {
        "default": {
            "runner": "nx/tasks-runners/default",
            "options": {
                "cacheableOperations": ["build", "test", "lint", "e2e"],
                "parallel": 3
            }
        }
    },
    "targetDefaults": {
        "build": {
            "dependsOn": ["^build"],
            "inputs": ["production", "^production"]
        }
    },
    "namedInputs": {
        "default": ["{projectRoot}/**/*", "sharedGlobals"],
        "production": ["default", "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)"],
        "sharedGlobals": []
    }
}

pnpm 工作区:轻量级方法

pnpm 工作区提供原生 monorepo 支持,无需额外工具。与 Turborepo 或 Nx 结合使用以进行缓存,或单独用于更简单的项目。

# pnpm-workspace.yaml
packages:
  - 'apps/*'
  - 'packages/*'

# Install all workspace dependencies
pnpm install

# Add a package to a specific workspace
pnpm add react --filter @myapp/web

# Add a local workspace package as dependency
# In apps/web/package.json:
{
    "dependencies": {
        "@myapp/ui": "workspace:*"
    }
}

# Run scripts across all packages
pnpm --filter '*' run build
pnpm --filter './apps/*' run dev
pnpm --filter '...@myapp/ui' run test  # ui and dependents

# Publish all public packages
pnpm publish -r --access public

远程缓存

远程缓存在开发人员和 CI 系统之间共享构建产物。缓存命中意味着即时构建——如果输入未更改,则无需重新编译。

# Turborepo Remote Cache (Vercel)
# Enables sharing build cache across developers and CI

# 1. Link to Vercel
npx turbo login
npx turbo link

# 2. Now CI builds share cache with local dev:
# CI run: builds from scratch, uploads to cache
# Developer: pulls cache, gets instant builds

# Self-host with Turborepo Remote Cache (open source)
# docker run -p 3000:3000 ducktors/turborepo-remote-cache

# .turbo/config.json (auto-generated by turbo link)
{
    "teamId": "team_xxx",
    "apiUrl": "https://vercel.com"
}

# Nx Cloud (similar offering from Nx)
# nx connect-to-nx-cloud
# Provides remote caching + task distribution

使用 Changesets 进行版本管理

Changesets 是 monorepo 中版本管理和发布包的标准工具。它跟踪哪些包发生了更改并生成 CHANGELOG.md 条目。

# Changesets — versioning and publishing for monorepos
# Works with npm/yarn/pnpm workspaces

pnpm add -D @changesets/cli
pnpm changeset init

# When you make a change that needs a version bump:
pnpm changeset
# → Interactive prompt: which packages changed, bump type (major/minor/patch)

# Creates a markdown file in .changeset/ describing the change
# Example .changeset/funny-bears-dance.md:
---
"@myapp/ui": minor
"@myapp/utils": patch
---

Add new Button component with loading state

# Apply changesets (bumps versions, updates CHANGELOG.md)
pnpm changeset version

# Publish all changed packages
pnpm changeset publish

Turborepo vs Nx vs pnpm 工作区

FeatureTurborepoNxpnpm Workspaces
Setup complexityLowMediumVery Low
Task cachingBuilt-inBuilt-inManual/external
Remote cacheVercel (free tier)Nx Cloud (paid)None built-in
Code generatorsNoYes (rich)No
Affected detectionBasic (--filter)Advanced (nx affected)Via Changesets
Language supportJS/TS focusedPolyglotAny
Learning curveLowMedium-HighLow

最佳实践

  • 从 pnpm 工作区 + Turborepo 开始——摩擦最小,缓存出色,文档良好。
  • 定义清晰边界:共享包在 packages/ 中,应用在 apps/ 中。切勿从共享包中导入应用代码。
  • 使用 Changesets 进行版本管理和发布。通过 GitHub Actions 在合并到 main 时自动化发布。
  • 尽早启用远程缓存——Turborepo 的 Vercel 缓存对爱好项目免费。CI 时间从几分钟减少到几秒钟。
  • 保持每个包的 package.json 明确:列出所有直接依赖,即使它们被提升。这可以防止幻影依赖错误。

常见问题

我应该使用 Turborepo 还是 Nx?

Turborepo 更简单,设置更快——对大多数 JavaScript/TypeScript 项目来说是理想的。Nx 具有更多功能:代码生成器、影响检测、模块边界执行,以及对多语言仓库的更好支持。如果需要这些功能或正在处理大型企业仓库,请选择 Nx。

Monorepo 和 polyrepo 有什么区别?

Monorepo 将所有代码存储在一个仓库中。Polyrepo(多仓库)每个包或服务有单独的仓库。Monorepo 使跨包重构更容易,确保所有包始终兼容。Polyrepo 拥有更简单的 CI 和更多团队自主权。

Turborepo 缓存如何工作?

Turborepo 对每个任务的输入(源文件、环境变量、依赖)进行哈希。如果哈希与之前的运行匹配,它从缓存(本地或远程)恢复输出。缓存是内容寻址的,所以相同的输入总是产生缓存命中。

monorepo 中可以有不同的包管理器吗?

不可以。monorepo 中的所有工作区必须使用相同的包管理器。工作区协议(workspace:*)在 npm、yarn 和 pnpm 中实现不同。选择一个并坚持使用。

如何在 monorepo 中处理环境变量?

为每个应用定义环境变量(每个应用有自己的 .env)。在 Turborepo 中,在 turbo.json globalEnv 中列出环境变量(用于所有任务)或每个任务的 env 数组。

相关工具

𝕏 Twitterin LinkedIn
这篇文章有帮助吗?

保持更新

获取每周开发技巧和新工具通知。

无垃圾邮件,随时退订。

试试这些相关工具

{ }JSON Formatter.git.gitignore Generator

相关文章

Bun 包管理器:2026年最快的JavaScript运行时与包管理器

2026年Bun完整指南:安装、工作区管理、脚本,以及为何比npm/yarn/pnpm更快。基准测试、迁移指南与实际使用。

Docker 多阶段构建:为生产环境优化镜像

2026年Docker多阶段构建完全指南:显著减小镜像体积、分离构建与运行依赖、创建优化的生产Docker镜像。

Git 分支策略:GitFlow vs 主干开发 vs GitHub Flow

对比 GitFlow、主干开发和 GitHub Flow 分支策略。学习分支结构、合并工作流、CI/CD 集成,以及如何为你的团队选择合适的策略。