pnpm 和npm 有什么区别?

pnpm 和 npm 都是 JavaScript/Node.js 的包管理工具,用于安装、管理和运行项目依赖(如 React、Express 等)。但它们在底层实现、性能、磁盘使用和依赖结构上有本质区别。


🧩 一、核心区别概览

特性 npm pnpm
全称 Node Package Manager Performant Node Package Manager
默认行为 将每个依赖复制到 node_modules 使用硬链接 + 符号链接共享依赖
磁盘占用 高(重复安装相同依赖) 极低(全局 store 共享)
安装速度 较慢(尤其大项目) 快 2--3 倍
依赖结构 扁平化(可能导致"幽灵依赖") 严格隔离(符合 package.json 声明)
兼容性 官方默认,100% 兼容 99% 兼容(极少数工具需适配)
配置文件 .npmrc .npmrc(支持更多 pnpm 专属选项)

🔍 二、深入解析关键差异

1. 依赖存储方式(最核心区别)

✅ npm:复制依赖

  • 每个项目都完整复制所有依赖到自己的 node_modules
  • 如果 10 个项目都用 lodash@4.17.21,磁盘上就有 10 份相同代码
text 复制代码
project1/
└── node_modules/
    └── lodash/      ← 复制一份
project2/
└── node_modules/
    └── lodash/      ← 再复制一份

✅ pnpm:全局 Store + 硬链接

  • 所有包只下载一次,存入 全局内容可寻址存储(store)
  • 项目通过 硬链接(hard link) 引用 store 中的文件
  • 磁盘节省高达 50--80%
text 复制代码
~/.pnpm/store/
└── v3/
    └── files/
        └── [hash] → lodash@4.17.21 的真实文件

project1/
└── node_modules/
    └── .pnpm/
        └── lodash@4.17.21 → 硬链接到 store
project2/
└── node_modules/
    └── .pnpm/
        └── lodash@4.17.21 → 同一个硬链接!

💡 硬链接 = 多个路径指向同一份物理数据,删除一个不影响其他。

2. 依赖解析与"幽灵依赖"问题

❌ npm 的"幽灵依赖"(Phantom Dependencies)

  • 因扁平化 node_modules,你的代码可能意外使用未声明的依赖
  • 示例:
js 复制代码
// package.json 只声明了 express
import _ from 'lodash'; // 但 lodash 被 express 的依赖间接安装了 → 能运行!
  • 后果:项目在别人机器上可能崩溃(因为依赖关系不明确)
    ✅ pnpm 的严格隔离
  • node_modules 结构是虚拟的,只暴露 package.json 中声明的依赖
  • 上述 import _ from 'lodash' 会直接报错:Module not found
  • 强制你显式声明所有依赖,提升项目健壮性

3. 性能对比

场景 npm pnpm
首次安装 慢(下载+解压+复制) 快(下载+硬链接)
二次安装 仍需复制 极快(直接链接)
CI/CD 环境 耗时长、缓存大 节省带宽和时间
Monorepo(多包项目) 重复安装 共享依赖,效率极高

📊 实测数据(100+ 依赖的项目):

  • npm install: 42 秒
  • pnpm install: 15 秒
  • 磁盘占用:npm 1.2 GB vs pnpm 300 MB

4. 命令兼容性

pnpm 几乎完全兼容 npm 命令:

功能 npm pnpm
安装依赖 npm install pnpm install
安装单个包 npm add lodash pnpm add lodash
运行脚本 npm run dev pnpm run dev(或简写 pnpm dev
全局安装 npm install -g typescript pnpm add -g typescript

⚠️ 唯一区别:

pnpm 不支持 npm audit,改用 pnpm audit(功能类似)

5. 特殊功能支持

功能 pnpm 支持 npm 支持
Workspaces(Monorepo) ✅ 原生高效 ✅(但较慢)
.npmrc 配置 ✅ + 扩展选项(如 allow-build-scripts
离线安装 ✅(从 store 复用) ❌(需重新下载)
依赖补丁(patch) pnpm patch

🛠 三、如何选择?

✅ 推荐使用 pnpm 如果:

  • 管理多个项目(节省磁盘)
  • 在做 Monorepo(如 Nx、Turborepo)
  • 重视依赖纯净性(避免幽灵依赖)
  • 在 CI/CD 中追求速度

✅ 仍可用 npm 如果:

  • 项目非常简单(学习/小 demo)
  • 团队已深度绑定 npm 生态
  • 某些老旧工具明确不兼容 pnpm(极少见)

🔮 趋势:

越来越多主流项目(如 Vite、Vue、Next.js 官方模板)默认推荐 pnpm。

🔄 四、迁移成本高吗?

几乎为零!

1. 安装 pnpm:

bash 复制代码
npm install -g pnpm

2.在项目中替换命令:

bash 复制代码
# 删除旧依赖
rm -rf node_modules package-lock.json

# 用 pnpm 安装
pnpm install

3.后续开发只需把 npm 换成 pnpm(或配置 alias)

💡 VS Code 用户:安装 pnpm extension,自动识别并提示使用 pnpm。

✅ 总结:一句话记住区别

npm 是"复印机"------每份依赖都复印一遍;

pnpm 是"图书馆"------所有项目共用同一本书,通过借阅(链接)使用。

npm pnpm
哲学 简单直接 高效精准
适合 初学者、小项目 专业开发、大型项目
未来 稳定但保守 快速演进,社区增长迅猛
相关推荐
To_OC2 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
vipbic3 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy3 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志3 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble4 小时前
c端系统,其实更像一个信息展示平台
前端
李姆斯5 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜6 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司6 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能
江华森7 小时前
Web 开发基础:HTTP 与 REST
前端·网络协议·http
IT_陈寒7 小时前
Redis的KEYS命令把我搞崩溃了,改用SCAN才活过来
前端·人工智能·后端