Skip to content
On this page

pnpm Workspaces 详解

简介

pnpm(performant npm)是一个快速、节省磁盘空间的包管理器,其 Workspaces 功能提供了一种高效的方式来管理 monorepo 中的多个包。pnpm 使用硬链接和符号链接来实现快速安装和节省磁盘空间。

启用 Workspaces

在根目录的 package.json 文件中添加 workspaces 配置:

json
{
  "private": true,
  "workspaces": [
    "packages/*",
    "components/*",
    "utils/*"
  ]
}

或者使用 pnpm-workspace.yaml 文件:

yaml
packages:
  # 所有 packages/ 目录下的包
  - 'packages/*'
  # 排除测试包
  - '!**/test/**'
  # 包含 examples/ 目录下的包
  - 'examples/**'

项目结构示例

my-monorepo/
├── pnpm-workspace.yaml
├── package.json
├── pnpm-lock.yaml
├── packages/
│   ├── ui/
│   │   ├── src/
│   │   ├── package.json
│   │   └── README.md
│   └── core/
│       ├── src/
│       ├── package.json
│       └── README.md
└── docs/
    └── ...

核心特性

1. 硬链接和符号链接

  • 使用硬链接避免重复下载相同的包
  • 使用符号链接减少磁盘空间占用
  • 快速安装,通常比 npm 和 yarn 快 2-100 倍

2. 网格结构(.pnpm/node_modules)

  • 每个包都有独立的 node_modules 结构
  • 避免幽灵依赖问题
  • 确保依赖关系的准确性

3. Workspace 协议

自动链接 workspace 内的包,无需发布到 npm:

json
{
  "name": "my-app",
  "dependencies": {
    "my-workspace-package": "workspace:*"
  }
}

常用命令

1. 安装依赖

bash
pnpm install

2. 在所有工作区运行脚本

bash
pnpm --recursive run test
# 或简写
pnpm -r run test

3. 在特定工作区运行脚本

bash
pnpm --filter <package-name> run dev

4. 添加依赖到所有包

bash
pnpm --recursive add <dependency>

5. 添加依赖到特定包

bash
pnpm --filter <package-name> add <dependency>

6. 过滤器语法

  • --filter <name>: 指定包
  • --filter <name>...: 指定包及其依赖
  • --filter ...<name>: 指定包及其依赖者
  • --filter ./path/to/package: 指定路径

高级配置

1. .npmrc 配置

在根目录创建 .npmrc 文件:

# 启用严格 peer 依赖
strict-peer-deps=true

# 并行度
fetching-concurrency=5

# 使用 pnpm 的 store 目录
store-dir=.pnpm-store

2. pnpm-lock.yaml

pnpm 使用专有的锁定文件格式,包含所有依赖的完整解析树。

性能优势

1. 磁盘空间节省

  • 所有包共享同一份依赖副本
  • 通过硬链接避免重复存储
  • 相比 npm/yarn 节省 2-3 倍空间

2. 安装速度

  • 依赖解析优化
  • 并行安装
  • 增量安装

3. 安全性

  • 防止幽灵依赖
  • 更严格的依赖解析
  • 可预测的依赖树

最佳实践

1. 包组织

  • 按功能或业务领域组织包
  • 保持包职责单一
  • 使用一致的命名约定

2. 依赖管理

  • 在根目录定义共享的开发依赖
  • 使用 workspace 协议引用内部包
  • 定期更新依赖版本

3. CI/CD 集成

  • 利用 pnpm 的增量安装特性
  • 使用缓存策略优化 CI 时间
  • 实施基于更改的智能构建

优缺点

优点

  • 极快的安装速度
  • 显著节省磁盘空间
  • 解决幽灵依赖问题
  • 支持非 JavaScript 项目
  • 强大的过滤和选择功能

缺点

  • 相对较新的生态系统
  • 某些工具可能不完全兼容
  • 学习曲线较陡峭

与其他工具对比

pnpm vs Yarn

  • pnpm 更节省磁盘空间
  • 安装速度通常更快
  • 解决幽灵依赖问题
  • Yarn 有更成熟的插件生态系统

pnpm vs npm

  • npm 7+ 也支持 workspaces
  • pnpm 在性能和磁盘使用方面更优
  • pnpm 的依赖模型更安全