pnpm,npm,yarn 区别,优缺点,历史进程一步一步走

814 阅读4分钟

本人对这部分的了解只是从网上进行过基本了解,如有缺陷,请喷我,麻烦指正一下,蟹蟹

灵感来源:@zxg_神说要有光

原地址:juejin.cn/post/712729…

搞一下

挑眉.gif

1. npm2

node版本降为4,npm版本会跟随降级为2。

在这个阶段node_modules是存在嵌套的,即,在node_modules还没有层级依赖优化的阶段

优点:只保留了npm的作用,原始npm,易于理解。

缺点: 没有依赖优化,只是简单的一层套一层,相同的包可能重复下载很多次;

而最致命的是windows文件路径最多260多个字符,像这种多层node_modules,多层依赖,极大概率超出路径最大限制,导致调用不到依赖

2.npm3/yarn 时代

在这个时代,npm2时期存在的主要问题基本上得到解决,但也有对应的缺点

优点: 层级依赖优化,将node_modules扁平化,只有一层,虽然还有node_modules嵌套但最多2层,主要历史问题得到解决。

缺点: 出现了新的问题,因为扁平化了。

下图这个看上去直观一些, image.png

比如说甲包依赖乙包,但是甲包通过打包后,dependencies表层中也只有依赖甲包,而不会有显示乙包依赖在dependencies表层,但因为扁平化的原因,层级是扁平了,但

明明没有声明在 dependencies表层 里的乙包依赖,但在代码里却可以 require 乙包进来。

幽灵依赖

表层依赖里看不见,但可以直接用

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

就像甲包原本有这个乙包依赖,写代码的时候又正好碰到责任心不太强的程序员,他只知道可以直接调用,有一天,甲包更新优化把乙包去依赖了,打包严格一点,这时候代码就跑不了了,对应的功能也就没有了,这个时候找bug是最恶心的,查看迭代也没有更新,方法使用也正确,但就是不能跑。

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

3. pnpm

只在全局仓库保存一份 npm 包的内容,其余的地方都 link 过去

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

包是从全局 store 硬连接(引用)到虚拟 store 的,这里的虚拟 store 就是 node_modules/.pnpm。

简单来说,所有的依赖都是从全局 store 硬连接(引用)到了 node_modules/.pnpm 下,然后之间通过软链接(新建文件,内容指向路径)来相互依赖。

把需要下载的包下载下来,这个时候,单个包像块砖一样,哪里需要哪里搬,但只下载一次,在node_modules下新建文件.pnpm,由.pnpm建立软连接,即地址路径。

image.png

优点:

1.最大的优点是节省磁盘空间,一个包全局只保存一份

2.因为通过链接的方式而不是复制,速度提升

3.npm3,yarn的幽灵依赖得到解决

总结:

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

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

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


学习来源作者:zxg_神说要有光
链接:juejin.cn/post/712729… 来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。