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
的文档。