什么是 Monorepo?pnpm workspace 如何使用?

Monorepo

将多个项目/包放在同一个 Git 仓库中管理。

my-monorepo/
├── packages/
│   ├── ui/          # UI 组件库
│   ├── utils/       # 工具库
│   ├── types/       # 类型定义
│   └── config/      # 共享配置
├── apps/
│   ├── web/         # Web 应用
│   └── admin/       # 管理后台
├── pnpm-workspace.yaml
└── package.json

Monorepo vs Polyrepo

特性 Monorepo Polyrepo
仓库 单一仓库 多个仓库
代码共享 容易 需发布 npm 包
版本管理 统一 各自独立
CI/CD 统一管理 各自配置
权限 全部可见 按仓库控制
适合 关联度高的项目 独立项目

pnpm workspace

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

常用命令

# 安装所有依赖(自动链接内部包)
pnpm install

# 在特定包中运行命令
pnpm --filter @my/ui build
pnpm --filter web dev

# 在所有包中运行命令
pnpm -r build

# 添加内部依赖
pnpm --filter web add @my/ui  # web 包依赖 @my/ui

# 添加外部依赖到所有包
pnpm -r add lodash

包间引用

// packages/ui/package.json
{
  "name": "@my/ui",
  "version": "1.0.0",
  "main": "./src/index.ts"
}

// apps/web/package.json
{
  "name": "@my/web",
  "dependencies": {
    "@my/ui": "workspace:*"  // 引用 workspace 内的包
  }
}

workspace:* 表示使用 workspace 内的版本,发布时自动替换为实际版本号。

Turborepo(构建加速)

// turbo.json
{
  "tasks": {
    "build": {
      "dependsOn": ["^build"],  // 先构建依赖的包
      "outputs": ["dist/**"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}
# 只构建变更影响的包
pnpm turbo build

# 并行运行 dev
pnpm turbo dev

Turborepo 优势

  1. 增量构建:只构建变更的包
  2. 缓存:相同输入不重复构建
  3. 并行执行:无依赖关系的任务并行
  4. 远程缓存:CI 和本地共享缓存

变更管理

# 检测哪些包有变更
pnpm turbo run build --filter=...[origin/main]

# Changesets(版本管理)
npx changeset          # 记录变更
npx changeset version  # 更新版本
npx changeset publish  # 发布到 npm

Monorepo 最佳实践

  1. 按职责分包:ui / utils / types / config
  2. 明确依赖方向:apps → packages,packages 之间尽量不互相依赖
  3. 统一工具链:ESLint / Prettier / TS 配置共享
  4. 使用 pnpm:比 npm/yarn 更节省磁盘空间(硬链接)
  5. CI 优化:只测试/构建变更的包

适合 Monorepo 的场景

不适合的场景

同分类其他题目