1. pnpm、npm 和 yarn 的区别
1.1 安装和速度
- pnpm:得益于全局内容可寻址存储,pnpm 的安装速度通常比 npm 和 yarn 快 2 倍以上,尤其在重复安装依赖时表现突出。
- yarn:通过并行下载和强大的缓存机制,安装速度也非常可观。
- npm:近年来性能有所提升,但整体速度仍可能落后于 pnpm 和 yarn。
1.2 磁盘空间效率
- pnpm:利用硬链接和符号链接,将依赖存储在全局位置,避免重复下载,显著节省磁盘空间。
- yarn:提供 Plug’n’Play(PnP)功能,减少 node_modules 的磁盘占用,特别适合 monorepo 项目。
- npm:采用扁平化的 node_modules 结构,虽然方便,但可能导致包重复,占用更多空间。
1.3 依赖管理
- pnpm:强制执行严格的依赖隔离,有效避免“幽灵依赖”(即未声明但意外可用的依赖)问题。
- yarn:通过 yarn.lock 文件确保依赖安装的一致性。
- npm:依赖 package-lock.json,但依赖树结构可能更复杂,偶尔会引发问题。
1.4 安全性
- pnpm:依赖管理严格,提供额外的安全保障。
- yarn 和 npm:在 2024 年都增强了安全功能,例如内置的漏洞检测工具。
1.5 使用场景
- pnpm:适合追求高性能的大型项目或 monorepo。
- npm:作为 Node.js 默认包管理器,适合小型项目或喜欢熟悉工具的用户。
- yarn:在依赖复杂的大型项目中表现优异,注重安全性和一致性。
2. pnpm 如何利用硬链接和符号链接节省磁盘空间
传统包管理器(如 npm)在处理依赖时存在重复下载和存储的问题,导致磁盘空间浪费。pnpm 通过全局依赖存储、硬链接和符号链接的机制,彻底优化了这一过程。
2.1 传统方式的不足
在 npm 中,每个项目都有独立的 node_modules 目录。安装依赖时,npm 会将所有包完整下载并存储到该目录下。即使多个项目依赖于同一版本的包(例如 lodash@4.17.21),npm 也会为每个项目分别下载和存储一份,造成磁盘空间的浪费。
2.2 pnpm 的全局依赖存储
pnpm 在系统上维护一个全局依赖存储(默认路径为 ~/.pnpm-store),所有依赖包都存储在这里。安装依赖时:
- 如果依赖已存在于全局存储中,pnpm 直接使用,无需下载。
- 如果不存在,pnpm 下载并存储到全局存储中,供后续使用。
这种机制确保了依赖只下载一次,避免重复下载。
2.3 硬链接的作用
pnpm 使用硬链接将全局存储中的依赖文件链接到项目的 node_modules 目录。硬链接指向文件系统中的同一个文件实体,具备以下优势:
- 节省空间:不复制文件内容,几乎不占用额外空间。
- 共享文件:多个项目共享同一份文件副本。
例如,两个项目依赖 lodash@4.17.21,pnpm 只在全局存储中保存一份,通过硬链接在项目中引用,磁盘上只有一份文件。
2.4 符号链接的辅助
pnpm 还使用符号链接来组织依赖关系:
- 构建依赖树:通过符号链接将子依赖指向全局存储中的实际文件。
- 兼容性:保持与 npm 相似的 node_modules 结构,开发者无需调整代码。
- 零空间占用:符号链接只是指针,不占用额外空间。
2.5 显著的磁盘空间节省
通过全局存储、硬链接和符号链接的组合,pnpm 显著减少了磁盘占用:
- 避免重复下载:依赖只下载一次。
- 减少文件副本:多个项目共享同一文件实体。
- 轻量级引用:符号链接不占用空间。
在 monorepo 项目中,pnpm 可以将磁盘占用从几十 GB 降至几 GB。
3. pnpm 能下载 npm 的所有包吗?
猜你想问:pnpm 能否完全替代 npm,下载 npm 注册表中的所有包?答案是理论上可以。pnpm 默认使用 npm 注册表(如 registry.npmjs.org),因此大多数包都可以直接下载。然而,某些包可能因为安装脚本或依赖结构的特殊性而出现兼容性问题。
解决办法:
- 使用 --node-linker=hoisted 参数调整依赖链接方式。
- 通过 .pnpmfile.cjs 钩子文件自定义安装行为。
这些配置可以帮助你处理少数不兼容的情况,确保 pnpm 的广泛适用性。
4. pnpm 的 Node.js 版本要求
猜你想问:pnpm 对 Node.js 版本有一定要求,具体如下:
- 普通版本:需要 Node.js 18.12 或更高版本。
- 可执行版本:pnpm 提供独立的可执行文件,内置 Node.js 运行时,无需额外安装高版本 Node.js。
- 与 npm 对比:npm 的版本要求随其更新而变化,例如 npm 最新版本需要 Node.js ^20.17.0 或 >=22.9.0。
如果你使用的是较旧的 Node.js 版本(例如 16.14.0),可以通过独立脚本安装 pnpm,具体方法见下文。
5. 如何使用 pnpm
5.1 安装 pnpm
根据你的环境,有以下几种安装方式:
- 通过 npm 全局安装(需要 Node.js 18.12+):
npm install -g pnpm - 使用 Corepack(Node.js 自带工具):
corepack enable pnpm - 独立脚本安装(适合低版本 Node.js,如 16.14.0):
curl -fsSL https://get.pnpm.io/install.sh | sh -
安装完成后,运行 pnpm --version 检查是否成功。
5.2 基本命令
pnpm 的命令与 npm 类似,但更高效:
- 初始化项目:pnpm init
- 添加依赖:pnpm add <package>(例如 pnpm add lodash)
- 安装所有依赖:pnpm install
- 运行脚本:pnpm run <script>(如 pnpm run dev)
- 移除包:pnpm rm <package>
6. 在低版本,如 Node.js 16.14.0 上使用 pnpm
如果你仍在使用 Node.js 16.14.0(低于 pnpm 普通版本的要求),可以通过独立脚本安装 pnpm。安装后,pnpm 会使用内置的 Node.js 运行时执行命令。不过,需要注意以下两点:
- 你安装的包必须与 Node.js 16.14.0 兼容。
- 如果遇到问题,可以尝试调整 pnpm 的配置或升级 Node.js 版本。
结语
无论你是追求性能的 monorepo 开发者,还是习惯 npm 的简单项目用户,亦或是需要 yarn 一致性的团队,了解 pnpm、npm 和 yarn 的区别都能帮助你选择合适的工具。pnpm 以其高效的磁盘利用率和快速安装速度,正在成为越来越多开发者的首选。
1270

被折叠的 条评论
为什么被折叠?



