pnpm 是面向 Node.js 的快速、节省磁盘空间的包管理器,主要用于依赖管理与工作区(workspaces)。当用户提到 "pnpm"、"pnpm install"、"pnpm workspace" 等场景时可使用。
主要能力
内容寻址存储:pnpm 将每个包版本在全局存储中仅保存一份。项目对存储建立硬链接,因此同一依赖在十个项目中使用时只占用一份磁盘空间。
严格的 node_modules:pnpm 创建非扁平的 node_modules。包只能访问它们显式声明的依赖,从而防止因提升(hoisting)而偶然可用的幽灵依赖。
速度:硬链接避免了重复下载与复制,并行解析使安装速度稳定快于 npm。
安装方式
通过 corepack(推荐,随 Node.js 16.13+ 提供): corepack enable corepack prepare pnpm@latest --activate
独立脚本: curl -fsSL https://get.pnpm.io/install.sh | sh -
通过 npm: npm install -g pnpm
通过 Homebrew: brew install pnpm
基本命令
pnpm install 从锁文件安装全部依赖 pnpm add lodash 添加生产依赖 pnpm add -D typescript 添加开发依赖 pnpm add -g vercel 全局添加 pnpm add lodash@4.17.21 指定版本 pnpm remove lodash 移除依赖 pnpm update 在 semver 范围内更新 pnpm update --latest 忽略范围更新到最新 pnpm dlx create-next-app@latest 不安装直接运行包
与 npm、yarn 的对应命令
安装全部:pnpm install / npm install / yarn 添加依赖:pnpm add pkg / npm install pkg / yarn add pkg 添加开发依赖:pnpm add -D pkg / npm install -D pkg / yarn add -D pkg 移除:pnpm remove pkg / npm uninstall pkg / yarn remove pkg 运行脚本:pnpm run dev / npm run dev / yarn dev 执行二进制:pnpm dlx pkg / npx pkg / yarn dlx pkg 更新:pnpm update / npm update / yarn up 审计:pnpm audit / npm audit / yarn audit 查看为何安装:pnpm why pkg / npm why pkg / yarn why pkg
工作区
pnpm-workspace.yaml 示例: packages:
- 'packages/*'
- 'apps/*'
过滤(Filtering):
pnpm --filter web run build 按包名 pnpm --filter "./apps/*" run build 按路径 glob pnpm --filter web... run build 该包及其依赖 pnpm --filter ...web run build 该包及其被依赖方 pnpm -r run build 所有工作区包 pnpm -r --parallel run build 并行执行全部
工作区协议:在 package.json 中用 workspace: 引用同级包,例如: { "dependencies": { "@myorg/shared": "workspace:*", "@myorg/utils": "workspace:^1.0.0" } }
发布时,pnpm 会将 workspace:* 替换为实际版本;workspace:^ 与 workspace:~ 会生成对应的 semver 范围。
Monorepo 模式
共享依赖:将共享的开发依赖放在工作区根目录,使用 -w 添加: pnpm add -Dw typescript eslint prettier
对等依赖(.npmrc): auto-install-peers=true strict-peer-dependencies=false
.npmrc 配置
shamefully-hoist=true 扁平化 node_modules(兼容性) auto-install-peers=true 自动安装对等依赖 strict-peer-dependencies=false 对等依赖不匹配时警告而非报错 enable-pre-post-scripts=true 运行 pre/post 生命周期脚本 use-node-version=20.11.0 固定 Node.js 版本 registry=https://registry.npmjs.org/ @myorg:registry=https://npm.pkg.github.com public-hoist-pattern[]=eslint 仅提升特定包 public-hoist-pattern[]=prettier store-dir=/path/to/custom/store 自定义存储位置
锁文件
pnpm 使用 pnpm-lock.yaml。在 monorepo 中它包含 importers 段落,存有各包的快照:
importers: apps/web: dependencies: react: specifier: ^18.2.0 version: 18.2.0 devDependencies: typescript: specifier: ^5.3.0 version: 5.3.3
应始终提交 pnpm-lock.yaml。在 CI 中使用 --frozen-lockfile。
补丁依赖
pnpm patch express@4.18.2 打开含包源码的临时目录 编辑文件后: pnpm patch-commit /tmp/patch-dir-xxxxx 生成补丁文件
这会在 package.json 中添加 patchedDependencies 条目: { "pnpm": { "patchedDependencies": { "express@4.18.2": "patches/express@4.18.2.patch" } } }
请提交 patches/ 目录。
覆盖(Overrides)
在整个依赖树中强制指定依赖版本: { "pnpm": { "overrides": { "lodash": "^4.17.21", "got@<11.8.5": ">=11.8.5", "express>debug": "~4.3.0" } } }
可用覆盖修复传递依赖漏洞或强制版本对齐。
脚本
pnpm run dev 运行 package.json 中的脚本 pnpm dev 简写(不会与 pnpm 命令冲突) pnpm --filter web run build 在特定包中运行 pnpm -r run test 在所有工作区包中运行 pnpm -r --parallel run lint 跨包并行执行
pnpm 默认不运行 pre/post 脚本,可在 .npmrc 中通过 enable-pre-post-scripts=true 启用。
存储管理
pnpm store path 打印全局存储位置 pnpm store prune 移除未被引用的包 pnpm store status 检查被修改的包 pnpm install --offline 仅从存储安装(无网络)
从工作区发布
pnpm -r publish --access public 发布全部公开包 pnpm -r publish --dry-run 先试运行 pnpm --filter "./packages/*" publish 发布子集
发布期间 pnpm 会将 workspace: 引用替换为真实版本号。
CI/CD
GitHub Actions 示例:
-
uses: pnpm/action-setup@v4 with: version: 9
-
uses: actions/setup-node@v4 with: node-version: 20 cache: 'pnpm'
-
run: pnpm install --frozen-lockfile
-
run: pnpm -r run build
-
run: pnpm -r run test
--frozen-lockfile 会在 pnpm-lock.yaml 过期时失败,防止意外改动锁文件。
对于通用 CI,可在构建之间缓存 pnpm store path 输出的目录。
从 npm/yarn 迁移
从 npm 迁移: rm -rf node_modules package-lock.json pnpm import 若存在 package-lock.json 则读取它 pnpm install
从 yarn 迁移: rm -rf node_modules yarn.lock pnpm import 若存在 yarn.lock 则读取它 pnpm install
迁移后:在 CI 中将 npm ci / yarn --frozen-lockfile 替换为 pnpm install --frozen-lockfile。若项目使用工作区,添加 pnpm-workspace.yaml。
适用场景
适合需要节省磁盘、加快依赖安装、要求严格依赖隔离的 Node.js 项目,尤其是使用工作区或 monorepo 的多包仓库,以及需要在 CI 中锁定依赖版本、修补依赖或统一依赖版本的团队。
限制
关于支持的操作系统、具体的性能基准数据、收费与价格信息等,资料暂未提供。