赞
踩
问题:node_modules的设计虽然能满足大部分的场景,但是其仍然存在着种种缺陷由于每个项目可能依赖成百上千个小模块,node_modules 目录的体积往往非常庞大,动辄几百MB甚至超过1GB。这不仅增加了存储负担,也影响了项目的克隆、备份和部署速度。
pnpm 的机制对于 yarn 和 npm 来说是降维打击。
包管理工具发展史,npm2 开始
用 node 版本管理工具把 node 版本降到 4,那 npm 版本就是 2.x 了。
然后找个目录,执行下 npm init -y,快速创建个 package.json。然后执行 npm install express,那么 express 包和它的依赖都会被下载下来:
展开 express,它也有 node_modules:
再展开几层,每个依赖都有自己的 node_modules:
也就是说 npm2 的 node_modules 是嵌套的。
存在的缺陷:
yarn 是怎么解决依赖重复很多次,嵌套路径过长的问题的呢?
处理方式:
存在的缺陷:
扁平化处理:
我们把 node_modules 删了,用 yarn 再重新安装下,执行 yarn add express:
这时候 node_modules 就是这样了:
全部铺平在了一层,展开下面的包大部分是没有二层 node_modules 的:
当然也有的包还是有 node_modules 的,比如这样:
为什么还有嵌套呢?
因为一个包是可能有多个版本的,提升只能提升一个,所以后面再遇到相同包的不同版本,依然还是用嵌套的方式。
npm 后来升级到 3 之后,也是采用这种铺平的方案了,和 yarn 很类似:
当然,yarn 还实现了 yarn.lock 来锁定依赖版本的功能,不过这个 npm 也实现了。
扁平化的方案也有相应的问题。而且还有一个问题,就是上面提到的依赖包有多个版本的时候,只会提升一个,那其余版本的包不还是复制了很多次么,依然有浪费磁盘空间的问题。
那 pnpm 是怎么解决这俩问题的呢?
**pnpm:**是一个更新的包管理工具,旨在提供比 npm 和 Yarn 更好的磁盘空间效率和更快的安装速度。
pnpm 通过使用软硬链接解决这个问题。
软链接:软链接是一个指向文件路径的引用。
硬链接:硬链接是一个指向文件数据的直接引用。
这样不会有复制多次的磁盘空间浪费,而且也不会有路径过长的问题。因为路径过长的限制本质上是不能有太深的目录层级,现在都是各个位置的目录的 link,并不是同一个目录,所以也不会有长度限制。
没错,pnpm 就是通过这种思路来实现的。
再把 node_modules 删掉,然后用 pnpm 重新装一遍,执行 pnpm install。
你会发现它打印了这样一句话:
包是从全局 store 硬连接到虚拟 store 的,这里的虚拟 store 就是 node_modules/.pnpm。
我们打开 node_modules 看一下:
确实不是扁平化的了,依赖了 express,那 node_modules 下就只有 express,没有幽灵依赖。
展开 .pnpm 看一下:
所有的依赖都在这里铺平了,都是从全局 store 硬连接过来的,然后包和包之间的依赖关系是通过软链接组织的。
比如 .pnpm 下的 expresss,这些都是软链接,
也就是说,所有的依赖都是从全局 store 硬连接到了 node_modules/.pnpm 下,然后之间通过软链接来相互依赖。
官方给了一张原理图,配合着看一下就明白了:
这就是 pnpm 的实现原理。
那么回过头来看一下,pnpm 为什么优秀呢?
首先,最大的优点是节省磁盘空间呀,一个包全局只保存一份,剩下的都是软硬连接,这得节省多少磁盘空间呀。
其次就是快,因为通过链接的方式而不是复制,自然会快。
这也是它所标榜的优点:
相比 npm2 的优点就是不会进行同样依赖的多次复制。
相比 yarn 和 npm3+ 呢,那就是没有幽灵依赖,也不会有没有被提升的依赖依然复制多份的问题。
这就已经足够优秀了,对 yarn 和 npm 可以说是降维打击。
Reference:https://juejin.cn/post/7127295203177676837?searchId=20240623222554B51B38FF0362E0D545BE
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。