Appearance
pnpm
pnpm 简介
pnpm 是目前最受欢迎的 Node 包管理器之一,以 “节省磁盘空间” 和 “速度快” 著称。
核心特点:
- 极度节省磁盘空间(依赖只存一份,用硬链接共享)
- 安装速度非常快
- 严格的依赖隔离(避免 “幽灵依赖” 问题)
pnpm 安装
使用 corepack 安装(推荐)
Node.js 16.13+ 自带 corepack。
corepack 介绍
corepack 是 Node.js 官方内置的包管理器管理工具,也就是 —— “包管理器的包管理器”。它的核心目标是确保团队和 CI 环境中使用一致的包管理器及版本,避免 “本地能跑、CI 失败” 的问题。
在项目中锁定包管理器版本(推荐):
Bash
corepack use pnpm@latest等价于在 package.json 中写入:
JSON
{
"packageManager": "pnpm@9.0.0"
}启用 corepack:
Bashcorepack enable安装并激活 pnpm(全局):
Bashcorepack prepare pnpm@latest --activate验证安装:
Bashpnpm -v
使用 npm 安装(全局)
安装:
Bashnpm install -g pnpm验证安装:
Bashpnpm -v
corepack 与全局安装对比
| 对比 | corepack | 使用 npm 全局安装 |
|---|---|---|
| 版本一致性 | 强(项目级) | 弱(全局单一版本) |
| CI 友好 | 是 | 一般 |
| 团队协作 | 强 | 弱 |
| 升级控制 | 精确 | 粗放 |
| 官方推荐 | 是 | 否 |
pnpm 基本使用
初始化项目
Bashpnpm init安装依赖
Bashpnpm install或:
Bashpnpm i添加依赖
生产依赖:
Bashpnpm add axios开发依赖:
Bashpnpm add -D typescript全局依赖:
Bashpnpm add -g serve移除依赖
Bashpnpm remove axios运行脚本
与 npm 完全一致:
Bashpnpm run build pnpm run dev可简写为:
Bashpnpm dev
推荐配置
在 package.json 添加 preinstall 脚本,防止团队误用 npm/yarn:
JSON
"scripts": {
"preinstall": "npx only-allow pnpm"
}从 npm 迁移到 pnpm
迁移前判断
适合迁移的项目:
- npm ≥ 7 的项目
- 使用
package-lock.json - 前端(Vue / React / Vite / Webpack / Next.js)
- Node.js 工具类项目
- monorepo(收益更大)
需要注意的项目(需要额外配置):
- 依赖 “幽灵依赖” 的老项目
- 使用非常规 postinstall 脚本
- 某些旧 CLI 工具假设扁平
node_modules
迁移步骤
提交 Git 保存当前状态
删除 npm 产物
Bashrm -rf node_modules rm -f package-lock.jsonpnpm 不使用
package-lock.json。如果希望保留当前依赖解析结果,最小化迁移风险,则可以先执行
pnpm import,然后再删除package-lock.json。pnpm import是一个 “低风险迁移工具”,用于在不重新解析依赖的前提下,将 npm / yarn 的 lockfile 转换为pnpm-lock.yaml。启用 corepack(仅需启用一次)
Bashcorepack enable安装并锁定 pnpm 版本
Bashcorepack use pnpm@latest这一步会在
package.json中写入:JSON{ "packageManager": "pnpm@9.0.0" }使用 pnpm 安装依赖
Bashpnpm install这会:
- 生成
pnpm-lock.yaml - 创建 pnpm 风格的
node_modules
- 生成
验证项目可运行
脚本可无需修改(pnpm 与 npm 命令兼容)。但推荐将
npm run改为pnpm:Bashpnpm dev pnpm test pnpm build
如果项目有幽灵依赖问题(pnpm 严格模式下报错 “缺少依赖”),在根目录创建 .npmrc 文件:
Text
shamefully-hoist=true这会模拟 npm 的 hoisting 行为,不推荐长期使用,最好是显式添加缺失依赖。或者针对特定包:
Text
public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=*prettier*