跳到主要内容
版本:10.x

pnpm vs npm

npm 的扁平化依赖树

从版本 3 开始,npm 维护了一个扁平化的依赖树。这减少了磁盘空间的浪费,但副作用是造成了混乱的 node_modules 目录。

另一方面,pnpm 通过使用硬链接和符号链接到全局的基于内容寻址的存储来管理 node_modules。这让你既能获得更少的磁盘空间使用量的好处,同时还能保持 node_modules 的整洁。如果你想了解更多,可以查看存储布局的文档。

pnpm 的合理 node_modules 结构的好处在于它通过使项目无法使用未在 package.json 中指定的模块来"帮助避免愚蠢的错误"。

安装

pnpm 不允许安装包而不将其保存到 package.json 中。如果在运行 pnpm add 时没有传入参数,包会被保存为常规依赖项。与 npm 一样,可以使用 --save-dev--save-optional 将包安装为开发依赖项或可选依赖项。

由于这个限制,使用 pnpm 的项目不会有任何多余的包,除非他们删除了一个依赖项并使其成为孤立包。这就是为什么 pnpm 的 prune 命令实现不允许你指定要删除的包 - 它总是会删除所有多余的和孤立的包。

目录依赖

目录依赖以 file: 前缀开头,并指向文件系统中的一个目录。与 npm 一样,pnpm 会为这些依赖创建符号链接。但与 npm 不同,pnpm 不会为文件依赖执行安装。

这意味着如果你有一个名为 foo<root>/foo)的包,其依赖项是 bar@file:../bar,当你在 foo 上运行 pnpm install 时,pnpm 不会为 <root>/bar 执行安装。

如果你需要同时在多个包中运行安装,例如在 monorepo 的情况下,你应该查看 pnpm -r 的文档。