node中npm yarn pnpm孰优孰劣???

news/2024/11/16 7:51:22/文章来源:https://www.cnblogs.com/never404/p/18297871

npm

npm2

node版本为4,npm版本就会将为2.x,此时我们执行下那

npm install express

分析下node_modules的目录结构。我们会发现, express 包和它的依赖都会被下载下来,展开展开 express,它也有 node_modules:
image
再展开几层,每个依赖都有自己的 node_modules:
image
也就是说 npm2 的 node_modules 是嵌套的。
这很正常呀?有什么不对么?这样其实是有问题的,多个包之间难免会有公共的依赖,这样嵌套的话,同样的依赖会复制很多次,会占据比较大的磁盘空间。这个还不是最大的问题,致命问题是 windows 的文件路径最长是 260 多个字符,这样嵌套是会超过 windows 路径的长度限制的。当时 npm 还没解决,社区就出来新的解决方案了,就是 yarn

yarn

yarn 是怎么解决依赖重复很多次,嵌套路径过长的问题的呢?铺平。所有的依赖不再一层层嵌套了,而是全部在同一层,这样也就没有依赖重复多次的问题了,也就没有路径过长的问题了。我们把 node_modules 删了,用 yarn 再重新安装下,执行 yarn add express:这时候 node_modules 就是这样了:
image
全部铺平在了一层,展开下面的包大部分是没有二层 node_modules 的:
image
当然也有的包还是有 node_modules 的,比如这样:
image
为什么还有嵌套呢?

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

npm 后来升级到 3 之后,也是采用这种铺平的方案了,和 yarn 很类似:
image
当然,yarn 还实现了 yarn.lock 来锁定依赖版本的功能,不过这个 npm 也实现了。yarn 和 npm 都采用了铺平的方案,这种方案就没有问题了么?并不是,扁平化的方案也有相应的问题。最主要的一个问题是幽灵依赖,也就是你明明没有声明在 dependencies 里的依赖,但在代码里却可以 require 进来。
但是这样是有隐患的,因为没有显式依赖,万一有一天别的包不依赖这个包了,那你的代码也就不能跑了,因为你依赖这个包,但是现在不会被安装了。
这就是幽灵依赖的问题。而且还有一个问题,就是上面提到的依赖包有多个版本的时候,只会提升一个,那其余版本的包不还是复制了很多次么,依然有浪费磁盘空间的问题。那社区有没有解决这俩问题的思路呢?当然有,这不是 pnpm 就出来了嘛。那 pnpm 是怎么解决这俩问题的呢?

pnpm

回想下 npm3 和 yarn 为什么要做 node_modules 扁平化?不就是因为同样的依赖会复制多次,并且路径过长在 windows 下有问题么?那如果不复制呢,比如通过 link。首先介绍下 link,也就是软硬连接,这是操作系统提供的机制,硬连接就是同一个文件的不同引用,而软链接是新建一个文件,文件内容指向另一个路径。当然,这俩链接使用起来是差不多的。如果不复制文件,只在全局仓库保存一份 npm 包的内容,其余的地方都 link 过去呢?这样不会有复制多次的磁盘空间浪费,而且也不会有路径过长的问题。因为路径过长的限制本质上是不能有太深的目录层级,现在都是各个位置的目录的 link,并不是同一个目录,所以也不会有长度限制。没错,pnpm 就是通过这种思路来实现的。再把 node_modules 删掉,然后用 pnpm 重新装一遍,执行 pnpm install。你会发现它打印了这样一句话:
image
包是从全局 store 硬连接到虚拟 store 的,这里的虚拟 store 就是 node_modules/.pnpm。

我们打开 node_modules 看一下:
image
确实不是扁平化的了,依赖了 express,那 node_modules 下就只有 express,没有幽灵依赖。

展开 .pnpm 看一下
image
所有的依赖都在这里铺平了,都是从全局 store 硬连接过来的,然后包和包之间的依赖关系是通过软链接组织的。

比如 .pnpm 下的 expresss,这些都是软链接,
image
也就是说,所有的依赖都是从全局 store 硬连接到了 node_modules/.pnpm 下,然后之间通过软链接来相互依赖。

官方给了一张原理图,配合着看一下就明白了
image
这就是 pnpm 的实现原理。

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

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

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

这也是它所标榜的优点:
相比 npm2 的优点就是不会进行同样依赖的多次复制。相比 yarn 和 npm3+ 呢,那就是没有幽灵依赖,也不会有没有被提升的依赖依然复制多份的问题。这就已经足够优秀了,对 yarn 和 npm 可以说是降维打击。

总结

pnpm 最近经常会听到,可以说是爆火。本文我们梳理了下它爆火的原因:npm2 是通过嵌套的方式管理 node_modules 的,会有同样的依赖复制多次的问题。npm3+ 和 yarn 是通过铺平的扁平化的方式来管理 node_modules,解决了嵌套方式的部分问题,但是引入了幽灵依赖的问题,并且同名的包只会提升一个版本的,其余的版本依然会复制多次。pnpm 则是用了另一种方式,不再是复制了,而是都从全局 store 硬连接到 node_modules/.pnpm,然后之间通过软链接来组织依赖关系。这样不但节省磁盘空间,也没有幽灵依赖问题,安装速度还快,从机制上来说完胜 npm 和 yarn。pnpm 就是凭借这个对 npm 和 yarn 降维打击的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/742389.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从0开始搭建博客

1. 概述 本篇博客,我教大家从0开始搭建一个 bolo博客,bolo 博客 和 solo 博客的区别是皮肤更加多,并且可以帐号密码登录。 本篇博客主要的内容如下:linux 安装 docker,设置docker镜像加速 docker 安装 nginx docker 的一些常用的命令 docker 安装 mysql 数据库 docker 安装…

OI 之后的故事 ~After Story~

回归综合 NOI 2023 后,理所当然是回归文化课的学习。 一开始,我惊讶地发现凭借学 OI 期间打下的数学基础及平时阅读英文题面积累的词汇量,我的数学和英语似乎还不错。 最头痛的无疑是语文和物理了。前者属于是玄学,你想到的点答案不一定有;对于后者,计算大题做一道错一道…

CF1936D. Bitwise Paradox-位运算、分治、线段树

link:https://codeforces.com/contest/1936/problem/D 题意:给两个长度为 \(n\) 的序列 \(a\) 和 \(b\),对一个区间 \([l,r]\),称 \([l,r]\) 是好的,若:\((b_l|\dots|b_r)\geq v\)。一个区间的 美丽值 定义为区间内 \(a\) 的最大值。现在有 \(q\) 个操作:1、\(b_i\to x\…

去哪儿故障定位

https://mp.weixin.qq.com/s/9f9PUUy8c-GCJLa0deIvuA

Cilium DSR 特性(转载)

Cilium DSR 特性Cilium DSR(转载) 一、环境信息主机 IPubuntu 10.0.0.234软件 版本docker 26.1.4helm v3.15.0-rc.2kind 0.18.0kubernetes 1.23.4ubuntu os Ubuntu 22.04.6 LTSkernel 5.15.0-106 内核升级文档使用 5.11.5 内核版本的 20.04 版本,发起 curl 请求无法代理到 p…

上传恶意代码服务器和数据库的操作

在通过访问端对服务器上传一句话木马的时候,我们需要对服务器进行部分操作: 1.打开服务器远程目录权限: (1)在windows服务器上,将文件夹的只读方式去掉; (2)在linux服务器上,将文件夹的权限改为pwd 2.开启数据库secure_file_priv权限 (1)我这里使用的是mysql5.7.2…

Zabbix 5.0 LTS URL 健康监测

更多细节详情看【zabbix官方文档】 需求 Zabbix 的URL健康监测功能允许你检测 Web 地址是否可用、正常工作以及响应速度。这对于监控网站的可用性和性能非常有用。例如,你可以监控公司网站、API 端点或其他关键服务的 URL。【官方表述 Web monitoring items】【官方表述 Trigg…

idea 修改 git 提交用户名

本项目 修改配置文件 修改当前项目目录下的 config 文件添加以下数据[user]name = **email = **@gmail.com全局修改 git config --global user.name gitlab注册用户名 git config --global user.email gitlab注册邮箱

ChatMoney,你的就业指导明灯

本文由 ChatMoney团队出品介绍说明 Hey!亲爱的小伙伴们,今天我要给大家带来一个职场利器——AI就业指导机器人!🤖 在这个充满变数的职场江湖,找到一份既能养家糊口又能实现自我价值的工作是多么重要。但是,职业道路上的选择和决策并不总是那么容易。有时候,我们需要的不…

AI就业指导机器人,你的专属职业导航灯!

本文由 ChatMoney团队出品介绍说明 Hey!亲爱的小伙伴们,今天我要给大家带来一个职场利器——AI就业指导机器人!🤖 在这个充满变数的职场江湖,找到一份既能养家糊口又能实现自我价值的工作是多么重要。但是,职业道路上的选择和决策并不总是那么容易。有时候,我们需要的不…

IDEA工具使用Git回滚代码

回滚已经commit但未push到远程仓库的代码点击git,然后右键选择你要退回的那条记录,选择undo commit(撤销提交) ,代码回滚就完成了! 此操作只是回滚,并不会删除你的操作内容回滚已经push到远程仓库的代码1. 先回滚提交到本地仓库的代码选择需要回滚到那个版本的提交记录,右键…

转-Java 异常处理的 20 个最佳实践,你知道几个?

‍ 作  者:武培轩 出  处:https://www.cnblogs.com/wupeixuan 原文链接:https://www.cnblogs.com/wupeixuan/p/11746117.html 异常处理是 Java 开发中的一个重要部分,是为了处理任何错误状况,比如资源不可访问,非法输入,空输入等等。Java 提供了几个异常处理特性,以…