PNPM 简介
npm(Node Package Manager)中文名为 Node 包管理器,是 Node.js 官方自带、全球最大的 JavaScript 软件包管理工具,也是前端 / Node.js 开发最基础、最常用的工具之一。
pnpm(Performant NPM),翻译过来就是高性能的 npm,旨在解决传统包管理器(如 npm 和 Yarn Classic)在性能、磁盘空间使用和依赖管理结构上的不足。
目前,pnpm 已成为前端生态最受欢迎的包管理器之一,被 Vue、Vite、Nuxt、Next.js、Svelte 等顶级开源项目,以及字节、阿里、腾讯等大厂的前端团队广泛采用,是公认的「当前最先进的包管理工具」。
pnpm 比传统方案安装包的速度快了两倍,以下是官方给出的benchmarks(对比了npm, pnpm, Yarn Classic, and Yarn PnP),在多种常见情况下,执行install的速度比较

pnpm 的核心优势,源于它从底层架构上彻底重构了依赖管理方式,精准解决了传统工具的多个顽疾:
1. 解决"磁盘空间浪费"与"安装速度慢"
使用 npm 时,若你有 100 个项目都依赖同一个包,硬盘中就会重复存储 100 份该依赖包的完整副本,造成大量磁盘空间浪费。
pnpm 则通过硬链接 搭配符号链接(软链接) 的机制,从根源上避免依赖重复拷贝,同时大幅提升安装效率:
- 增量存储 :针对同一依赖包的不同版本,pnpm 仅会存储版本间存在差异的文件 。例如新版本仅修改了单个文件,
pnpm update只需新增这一个文件至存储仓库,无需完整保存整个依赖包。 - 全局共享 :pnpm 会在本地维护一个全局内容寻址存储库 (默认路径为
~/.pnpm-store),所有项目用到的依赖包,在全局仓库仅留存一份真实物理文件。 - 零拷贝 :项目安装依赖时,pnpm 不会复制文件,而是通过硬链接 (项目里
/node_modules/.pnpm/)指向全局仓库中的源文件; - 兼容结构 :最后通过软链接 搭建符合 Node.js 规范的
node_modules根目录结构,让项目和构建工具能正常识别依赖,同时为依赖隔离打下基础。
2. 解决"幽灵依赖" (Phantom Dependencies)
幽灵依赖是 npm 体系中一个极具隐患的问题。npm 会通过依赖扁平化(Dependency Hoisting) 机制,将间接依赖提升至 node_modules 根目录,这就导致项目可以直接引入并使用那些并未在自身 package.json 中声明的依赖包。这类依赖之所以能被访问,只是因为它们是其他直接依赖的子依赖,并在依赖提升后暴露在了根目录下。
幽灵依赖看似能简化开发,实则暗藏风险:
- 依赖版本不可控,易造成构建结果不稳定,排查问题时需要逐层追溯依赖树,调试与维护成本极高;
- 不同环境下依赖结构可能存在差异,极易出现本地正常、线上构建失败的情况;
- 间接依赖若存在安全漏洞,开发者往往难以感知,会带来潜在的安全风险。
pnpm 则通过虚拟存储(Virtual Store) 机制,从底层解决这一痛点:
它在项目内模拟传统 node_modules 的嵌套结构,同时在 .pnpm 目录下以包名 + 版本号的形式为每个版本创建独立文件夹,通过硬链接从全局仓库精准关联对应版本的真实文件;
再通过根目录node_modules 的符号链接,构建出严格的依赖隔离层级。
最终实现不同版本的依赖独立存放、精准引用、互不干扰,从根源上杜绝版本冲突,完美支持 Monorepo 场景下多子包的不同版本依赖,保障复杂依赖关系下项目的稳定运行。
3. 解决"多版本依赖冲突"
在实际项目中,常会出现不同第三方库依赖同一依赖包不同版本的情况(如部分组件库依赖 React 17,另一部分依赖 React 18)。
npm 针对该问题采用嵌套 node_modules 的基础隔离方案,将不兼容的版本安装在对应第三方包的内部目录中。但此方案存在明显缺陷:依赖目录结构变得杂乱无章,Windows 系统下易因路径过长导致报错,大量重复嵌套的依赖会造成磁盘空间浪费;加之 npm 保留的扁平化逻辑无法实现严格隔离,版本冲突与项目运行异常的风险始终存在。
pnpm 使用了一种叫做虚拟存储(Virtual Store) 机制。它在项目内模拟传统 node_modules 的嵌套结构,同时在 .pnpm 目录下以包名 + 版本号 的形式为每个版本创建独立文件夹,通过硬链接从全局仓库精准关联对应版本的真实文件;再通过根目录 node_modules 的符号链接,构建出严格的依赖隔离层级。最终实现不同版本的依赖独立存放、精准引用、互不干扰,从根源上杜绝版本冲突,保障复杂依赖关系下项目的稳定运行。
总结:三层架构
| 层级 | 位置 | 内容性质 | 作用 |
|---|---|---|---|
| L1: 全局仓库 | ~/.pnpm-store |
真实文件 | 节省磁盘空间,所有项目共享。 |
| L2: 项目仓库 | node_modules/.pnpm |
硬链接 | 管理项目内复杂的依赖版本和嵌套关系。 |
| L3: 暴露接口 | node_modules/ |
符号链接 | 方便构建工具寻找依赖。 |

PNPM 安装
必须先安装 Node.js (npm 自带),先去官网装:nodejs.org/(选 LTS 版本)
bash
# 安装 pnpm
npm install -g pnpm
# 检查是否安装成功
pnpm -v
# 初始化 pnpm
pnpm setup
# 尝试升级
pnpm self-update
# 国内换源
pnpm config set registry https://registry.npmmirror.com/
PNPM 快速上手
以下是列出常用的命令,具体可以参考官网管理依赖
安装依赖包
csharp
pnpm add <pkg>
| 命令 | 说明 |
|---|---|
pnpm add sax |
安装并保存到 dependencies(生产依赖) |
pnpm add -D sax |
安装并保存到 devDependencies(开发依赖) |
pnpm add -O sax |
安装并保存到 optionalDependencies(可选依赖) |
pnpm add -g sax |
全局安装 |
pnpm add sax@next |
安装 next 标签对应的版本 |
pnpm add sax@3.0.0 |
安装指定版本 3.0.0 |
安装项目全部依赖
bash
pnpm install
# 或简写 pnpm i
更新依赖
bash
pnpm update
# 或简写 pnpm up
| 命令 | 说明 |
|---|---|
pnpm up |
在 package.json 约定的版本范围内,更新所有依赖 |
pnpm up --latest |
忽略版本范围约束,更新所有依赖到最新版 |
pnpm up foo@2 |
将 foo 更新到 v2 系列的最新版本 |
pnpm up "@babel/*" |
更新 @babel scope 下的所有依赖 |
删除依赖
csharp
pnpm remove # 或简写 pnpm rm
pnpm uninstall # 或简写 pnpm un
# remove 和 uninstall 作用上完全等价
运行脚本
-
执行
package.json中定义的脚本:xmlpnpm run <script> -
运行测试脚本:
bashpnpm test -
运行启动脚本:
sqlpnpm start # 或 pnpm run start
初始化 / 创建项目
从 create-* 或 @foo/create-* 模板快速创建项目:
css
pnpm create <starter> [项目名]
示例:
lua
pnpm create react-app my-app
常用进阶小技巧
-
清理无用依赖
pnpm prune -
查看依赖来源(排查冲突用)
matlabpnpm why react -
删除 node_modules(比手动删更快)
pnpm store prune