pnpm 是凭什么对 npm 和 yarn 降维打击的

最近大家是不是经常听到 pnpm?我也是如此。今天我研究了它的机制,确实非常厉害,可以说是对 yarn 和 npm 的降维打击。

那么,pnpm 到底好在哪里呢?我们一起来看看。

我们从包管理工具的发展历史开始讲起,从 npm2 说起:

npm2 需要将 node 版本降到 4,那 npm 版本就是 2.x。

pnpm 是凭什么对 npm 和 yarn 降维打击的然后找个目录,执行 npm init -y,快速创建一个 package.json

接着执行 npm install express,这时 express 包及其依赖都会被下载下来:

pnpm 是凭什么对 npm 和 yarn 降维打击的展开 express,你会发现它也有自己的 node_modules:

pnpm 是凭什么对 npm 和 yarn 降维打击的再展开几层,你会看到每个依赖都有自己的 node_modules:

pnpm 是凭什么对 npm 和 yarn 降维打击的也就是说,npm2 的 node_modules 是嵌套的。

这很正常,对吗?有什么问题吗?

其实是有问题的,多个包之间难免会有公共的依赖,这样嵌套的话,同样的依赖会被复制很多次,会占用大量的磁盘空间。

这还不是最大的问题,致命的问题是 windows 的文件路径最长限制在 260 多个字符,这样嵌套会超过 windows 路径的长度限制。

当时 npm 还没有解决这个问题,社区就推出了新的解决方案,即 yarn:

yarnyarn 是如何解决依赖重复和嵌套路径过长的问题的呢?

通过铺平。所有的依赖不再一层层嵌套,而是全部在同一层,这样就不会有依赖重复多次的问题,也不会有路径过长的问题。

我们删除 node_modules,然后用 yarn 重新安装,执行 yarn add express:

这时候 node_modules 看起来是这样的:

pnpm 是凭什么对 npm 和 yarn 降维打击的所有的依赖都铺平在一层,大部分包下面没有二层 node_modules:

pnpm 是凭什么对 npm 和 yarn 降维打击的当然,也有一些包还是有 node_modules 的,比如这样:

pnpm 是凭什么对 npm 和 yarn 降维打击的为什么还会有嵌套呢?

因为一个包可能有多个版本,提升只能提升一个,所以后面遇到相同包的不同版本,依然会用嵌套的方式。

npm 后来升级到 3 之后,也采用了这种铺平的方案,和 yarn 非常类似:

pnpm 是凭什么对 npm 和 yarn 降维打击的当然,yarn 还实现了 yarn.lock 来锁定依赖版本的功能,不过这个 npm 也实现了。

yarn 和 npm 都采用了铺平的方案,这种方案就没有问题了吗?

并不是,扁平化的方案也有相应的问题。

最主要的一个问题是幽灵依赖,也就是你明明没有在 dependencies 中声明过的依赖,但在代码里却可以 require 进来。

这个也很容易理解,因为都铺平了嘛,那依赖的依赖也是可以找到的。

但是这样是有隐患的,因为没有显式依赖,万一有一天别的包不依赖这个包了,那你的代码也就不能跑了,因为你依赖这个包,但现在不会被安装了。

这就是幽灵依赖的问题。

而且还有一个问题,就是上面提到的依赖包有多个版本的时候,只会提升一个,那其余版本的包不还是复制了很多次么,依然有浪费磁盘空间的问题。

那社区有没有解决这两个问题的思路呢?

当然有,这就是 pnpm 出现的原因。

那么,pnpm 是如何解决这两个问题的呢?

降重鸟 降重鸟

要想效果好,就用降重鸟。AI改写智能降低AIGC率和重复率。

降重鸟 113 查看详情 降重鸟

pnpm回想一下,npm3 和 yarn 为什么要做 node_modules 扁平化?不就是因为同样的依赖会复制多次,并且路径过长在 windows 下有问题么?

那如果不复制呢,比如通过 link。

首先介绍一下 link,也就是软硬连接,这是操作系统提供的机制,硬连接就是同一个文件的不同引用,而软链接是新建一个文件,文件内容指向另一个路径。当然,这两个链接使用起来是差不多的。

如果不复制文件,只在全局仓库保存一份 npm 包的内容,其余的地方都 link 过去呢?

这样不会有复制多次的磁盘空间浪费,而且也不会有路径过长的问题。因为路径过长的限制本质上是不能有太深的目录层级,现在都是各个位置的目录的 link,并不是同一个目录,所以也不会有长度限制。

没错,pnpm 就是通过这种思路来实现的。

再把 node_modules 删掉,然后用 pnpm 重新装一遍,执行 pnpm install。

你会发现它打印了这样一句话:

pnpm 是凭什么对 npm 和 yarn 降维打击的包是从全局 store 硬连接到虚拟 store 的,这里的虚拟 store 就是 node_modules/.pnpm。

我们打开 node_modules 看一下:

pnpm 是凭什么对 npm 和 yarn 降维打击的确实不是扁平化的了,依赖了 express,那 node_modules 下就只有 express,没有幽灵依赖。

展开 .pnpm 看一下:

pnpm 是凭什么对 npm 和 yarn 降维打击的所有的依赖都在这里铺平了,都是从全局 store 硬连接过来的,然后包和包之间的依赖关系是通过软链接组织的。

比如 .pnpm 下的 express,这些都是软链接,

pnpm 是凭什么对 npm 和 yarn 降维打击的也就是说,所有的依赖都是从全局 store 硬连接到了 node_modules/.pnpm 下,然后之间通过软链接来相互依赖。

官方给了一张原理图,配合着看一下就明白了:

pnpm 是凭什么对 npm 和 yarn 降维打击的这就是 pnpm 的实现原理。

那么回过头来看一下,pnpm 为什么优秀呢?

首先,最大的优点是节省磁盘空间呀,一个包全局只保存一份,剩下的都是软硬连接,这得节省多少磁盘空间呀。

其次就是快,因为通过链接的方式而不是复制,自然会快。

这也是它所标榜的优点:

pnpm 是凭什么对 npm 和 yarn 降维打击的相比 npm2 的优点就是不会进行同样依赖的多次复制。

相比 yarn 和 npm3+ 呢,那就是没有幽灵依赖,也不会有没有被提升的依赖依然复制多份的问题。

这就已经足够优秀了,对 yarn 和 npm 可以说是降维打击。

总结pnpm 最近经常会听到,可以说是爆火。本文我们梳理了下它爆火的原因:

npm2 是通过嵌套的方式管理 node_modules 的,会有同样的依赖复制多次的问题。

npm3+ 和 yarn 是通过铺平的扁平化的方式来管理 node_modules,解决了嵌套方式的部分问题,但是引入了幽灵依赖的问题,并且同名的包只会提升一个版本的,其余的版本依然会复制多次。

pnpm 则是用了另一种方式,不再是复制了,而是都从全局 store 硬连接到 node_modules/.pnpm,然后之间通过软链接来组织依赖关系。

这样不但节省磁盘空间,也没有幽灵依赖问题,安装速度还快,从机制上来说完胜 npm 和 yarn。

pnpm 就是凭借这个对 npm 和 yarn 降维打击的。

以上就是pnpm 是凭什么对 npm 和 yarn 降维打击的的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/398130.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月6日 18:21:43
下一篇 2025年11月6日 18:22:52

相关推荐

发表回复

登录后才能评论
关注微信