Files
2026-07-13 21:35:53 +08:00

3.8 KiB
Raw Permalink Blame History

name, description
name description
pnpm-workspaces 通过工作空间实现 monorepo 支持,用于管理多个包

pnpm Workspaces

pnpm 通过工作空间(workspaces)内置支持 monorepo(多包仓库)。

设置工作空间

在仓库根目录创建 pnpm-workspace.yaml

packages:
  # 包含 packages/ 目录下的所有包
  - 'packages/*'
  # 包含所有应用
  - 'apps/*'
  # 包含嵌套的包
  - 'tools/*/packages/*'
  # 排除测试目录
  - '!**/test/**'

工作空间协议

使用 workspace: 协议引用本地包:

{
  "dependencies": {
    "@myorg/utils": "workspace:*",
    "@myorg/core": "workspace:^",
    "@myorg/types": "workspace:~"
  }
}

协议变体

协议 行为 发布时转换
workspace:* 任意版本 实际版本(如 1.2.3
workspace:^ 兼容版本 ^1.2.3
workspace:~ 补丁版本 ~1.2.3
workspace:^1.0.0 Semver 范围 ^1.0.0

过滤包

使用 --filter 在特定包上运行命令:

# 按包名
pnpm --filter @myorg/app build
pnpm -F @myorg/app build

# 按目录路径
pnpm --filter "./packages/core" test

# Glob 模式
pnpm --filter "@myorg/*" lint
pnpm --filter "!@myorg/internal-*" publish

# 所有包
pnpm -r build
pnpm --recursive build

基于依赖关系的过滤

# 包及其所有依赖
pnpm --filter "...@myorg/app" build

# 包及其所有依赖者
pnpm --filter "@myorg/core..." test

# 双向
pnpm --filter "...@myorg/shared..." build

# 自 git 引用以来的变更
pnpm --filter "...[origin/main]" test
pnpm --filter "[HEAD~5]" lint

工作空间命令

安装依赖

# 安装所有工作空间包
pnpm install

# 向特定包添加依赖
pnpm --filter @myorg/app add lodash

# 添加工作空间依赖
pnpm --filter @myorg/app add @myorg/utils

运行脚本

# 在所有包含该脚本的包中运行
pnpm -r run build

# 按拓扑顺序运行(依赖优先)
pnpm -r --workspace-concurrency=1 run build

# 并行运行
pnpm -r --parallel run test

# 流式输出
pnpm -r --stream run dev

执行命令

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

# 在特定包中运行
pnpm --filter "./packages/**" exec rm -rf dist

工作空间设置

.npmrcpnpm-workspace.yaml 中配置:

# 自动链接工作空间包
link-workspace-packages=true

# 优先使用工作空间包而非注册表
prefer-workspace-packages=true

# 单一锁文件(推荐)
shared-workspace-lockfile=true

# 工作空间协议处理方式
save-workspace-protocol=rolling

# 并发工作空间脚本数
workspace-concurrency=4

发布工作空间

发布时,workspace: 协议会被转换:

// 发布前
{
  "dependencies": {
    "@myorg/utils": "workspace:^"
  }
}

// 发布后
{
  "dependencies": {
    "@myorg/utils": "^1.2.3"
  }
}

从 CI 发布时使用 --no-git-checks

pnpm publish -r --no-git-checks

最佳实践

  1. 对内部依赖使用 workspace 协议
  2. 启用 link-workspace-packages 以实现自动链接
  3. 使用共享锁文件 以保证一致性
  4. 构建时按依赖过滤 以确保正确的顺序
  5. 使用目录(catalogs 管理共享的外部依赖版本

项目结构示例

my-monorepo/
├── pnpm-workspace.yaml
├── package.json
├── pnpm-lock.yaml
├── packages/
│   ├── core/
│   │   └── package.json
│   ├── utils/
│   │   └── package.json
│   └── types/
│       └── package.json
└── apps/
    ├── web/
    │   └── package.json
    └── api/
        └── package.json