Pnpm:包管理的新星,如何颠覆 Npm 和 Yarn

在探索现代 JavaScript 生态系统时,我们常常会遇到新兴技术的快速迭代和改进。其中,包管理工具的发展尤为重要,因为它们直接影响开发效率和项目性能。最近,pnpm 作为一种新的包管理工具引起了广泛关注。它不仅挑战了传统工具如 npmYarn,还提供了一些独特的优势,使其在许多方面超越了前辈。

为了更好地理解 pnpm 的优势,我们从包管理工具的历史开始探索,从 npm2 开始的各个阶段。我们将看到 pnpm 如何通过技术创新解决历史遗留问题,并极大地提高性能和效率。接下来,深入了解 pnpm 的核心机制以及它如何改变开发者处理依赖管理的方式。

npm2

使用 Node 版本管理工具将 Node 版本降级到 4,然后 npm 版本将是 2.x

bbe7d64c7b951605784e01781d63c800.png

在一个目录中运行 npm init -y 快速创建一个 package.json 文件。

然后运行 npm install express,express 包及其依赖项将被下载:

087821fc2cbc072f2826bc815feacd4d.png

展开 express,它也有 node_modules

176109b05ffc34cac8a505c875573082.png

继续展开几层,每个依赖项都有自己的 node_modules

8acbf93385c7ffc9b715ccbf3f765979.png

换句话说,npm2 的 node_modules 是嵌套的。

这正常吗?这有什么问题吗?

实际上,这确实有问题。多个包不可避免地具有共同的依赖项。当像这样嵌套时,相同的依赖项将被多次重复,占用了相对较大的磁盘空间。

这还不是最大的问题;致命的问题是 Windows 中文件路径的最大长度超过 260 个字符。像这样嵌套会超过 Windows 的路径长度限制。

在 npm 尚未解决这个问题时,社区出现了一个新的解决方案:yarn

yarn

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

扁平化。所有依赖项不再逐层嵌套,而是全部处于同一层级,因此不再存在重复依赖或路径过长的问题。

我们删除 node_modules,使用 Yarn 重新安装并执行 yarn add express

此时,node_modules 看起来像这样:

06956e1a3492738a21df03a3e71989f4.png

所有依赖项都在同一层级,大多数包在其下没有第二层 node_modules

93536310ce3762a22b84975ea45bcef4.png

当然,有些包仍然有 node_modules,例如这个:

815558361b01a81533650a44cd7029de.png

为什么仍然存在嵌套?

因为一个包可能有多个版本,并且只有一个版本可以被提升。因此,当遇到不同版本的同一包时,仍然使用嵌套。

npm 升级到版本 3 后,也采用了这种扁平化解决方案,与 yarn 非常相似:

53a735e7f5a691e3e2e3e7358fcc1224.png

当然,yarn 也实现了 yarn.lock 的功能来锁定依赖项版本,但 npm 也实现了这一点。

yarnnpm 都采用了扁平化解决方案。这种方法没有问题吗?

不完全是,扁平化解决方案也有自己的问题

主要问题是幽灵依赖,这意味着在代码中可以引入未在依赖项部分声明的依赖项。

这很容易理解,因为一切都是扁平化的,所以可以找到依赖项的依赖项。

然而,这带来了风险,因为没有明确的依赖声明,如果有一天另一个包不再依赖于那个包,你的代码将无法运行,因为依赖于它,但现在没有安装。

这就是幽灵依赖的问题

另一个问题是多个版本的依赖项,如上所述。只有一个版本会被提升,而其他版本则会重复多次,导致磁盘空间浪费。

社区有解决这两个问题的想法吗?

当然有!这就是为什么引入了 pnpm

pnpm

回顾一下,为什么 npm3yarn 扁平化 node_modules?不就是因为相同的依赖项会被多次重复,并且长路径可能会在 Windows 上引发问题吗?

如果我们不重复它们,而是使用链接呢?

首先,介绍链接。它是操作系统提供的软链接和硬链接。硬链接是同一个文件的不同引用,而符号链接会创建一个新文件,其内容指向另一个路径。当然,这两种链接的使用方式是类似的。

如果不复制文件,而是将 npm 包的唯一副本存储在全局仓库中,并将其他位置链接到它呢?

这样就不会因多次复制而浪费磁盘空间,也不会有路径过长的问题。路径长度的限制本质上意味着不应该有太深的目录层级;现在所有位置的目录是链接在一起的,而不是在同一个目录中,因此没有长度限制。

是的,pnpm 通过这种方法实现了这一点。

再次删除 node_modules,然后使用 pnpm 通过运行 pnpm install 重新安装。

你会注意到它打印出这样一句话:

81d07585d7dbeed4dccc2b09875ecf13.png

软件包从全局存储硬链接到虚拟存储,这里的虚拟存储是 node_modules/.pnpm

我们打开 node_modules 看一看。

183653422b5b2526f6d55a72119768cd.png

确实不是扁平的,依赖 express,所以在 node_modules 下只有 express,没有任何幽灵依赖。

展开 .pnpm 看看:

9d322ffb7a06115d185ee80414ce0a21.png

所有依赖项都在这里解决,全部从全局仓库直接链接过来,并通过符号链接组织包之间的依赖关系。

例如,.pnpm 下的 express,都是符号链接。

625a41e037dd0f16cd4e2a9733610ad3.png

换句话说,所有依赖项都是从全局仓库硬链接到 node_modules/.pnpm,然后它们通过符号链接相互依赖。

官方提供了一个示意图,结合起来看很清楚:

ae68435e05f539a97f76e52ce9e51d22.png

这就是 pnpm 的实现原理。

pnpm 的优越性

首先,最大的优势是节省磁盘空间。包只在全局保存一份,其余的都是符号链接或硬链接。这节省了大量磁盘空间。

其次,它很快,因为它使用链接而不是复制,这自然使它更快。

这些也是它所宣称的优势:

600dd09771bbf79e8fa2f1b062dc65e2.png

相比 npm2,优势在于不会多次重复相同的依赖项。

相比 yarn 和 npm3+,没有幽灵依赖,也没有未提升依赖项的重复问题。

这已经足够优秀,可以说是对 yarn 和 npm 的一次打击。

结语

最近,pnpm 频繁被提及,可以说是当下的趋势。在本文中,我们总结了其受欢迎的原因:

npm2 以嵌套方式管理 node_modules,导致多次重复依赖项的问题。

npm3+ 和 yarn 通过扁平化方式管理 node_modules,解决了嵌套方式的一些问题,但引入了幽灵依赖的问题。此外,同名包只有一个版本被提升,而其他版本仍会重复。

pnpm 通过不复制文件,而是从全局仓库硬链接到 node_modules/.pnpm,并通过符号链接组织依赖关系,解决了这些问题。

这不仅节省了磁盘空间,消除了幽灵依赖问题,还加快了安装速度。从机械角度来看,pnpm 超越了 npm 和 yarn。

通过这种对 npm 和 yarn 的创新方法,pnpm 正在通过简化依赖管理的方式产生影响。

最后:

vue2与vue3技巧合集

VueUse源码解读

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

激励-保健理论和公平理论

激励-保健理论 herzberg的激励-保健理论中,保健因素是context of a job,激励因素是content of a job。 context of a job是受组织控制的因素,比如工作条件,基本工资,公司政策等,个人无法支配。content of…

【深入浅出MySQL】「数据同步架构」分析探索Canal开源技术原理和架构

分析探索Canal开源技术原理和架构 背景说明Canal基本介绍Canal作用方向MySQL同步原理Binlog Dump交互Binlog的协议模型Canal的模拟slave角色Canal的消费订阅 Canal Server模块Canal Instance模块参考资料类似开源项目 背景说明 在早期阶段,阿里巴巴B2B公司由于其在…

WPF文本框中加提示语

效果&#xff1a; WPF中貌似不能像winfrom里一样直接加提示语&#xff0c;需要使用TextBox.Style&#xff0c;将Trigger标签插入进去。 贴源码&#xff1a; <WrapPanel Name"TakeOverExpressNo1"><Label Content"物流单号&#xff1a;"><…

力扣SQL50 每月交易 I 求和 SUM(条件表达式) DATE_FORMAT(日期,指定日期格式)

Problem: 1193. 每月交易 I &#x1f468;‍&#x1f3eb; 参考题解 Code select DATE_FORMAT(trans_date, %Y-%m) AS month,country,count(*) as trans_count,count(if(state approved, 1, NULL)) as approved_count,sum(amount) as trans_total_amount,sum(if(state appr…

MS17-010(Eternal blue永恒之蓝)漏洞利用+修复方法

目录 一、漏洞简介 漏洞原理 影响版本 二、漏洞复现 三、复现过程 1、扫描局域网内的C段主机&#xff08;主机发现&#xff09; 扫描结果&#xff1a; 2.使用MSF的永恒之蓝漏洞模块 3.对主机进行扫描&#xff0c;查看其是否有永恒之蓝漏洞 4.准备攻击 四、漏洞利用 …

华为---OSPF被动接口配置(四)

9.4 OSPF被动接口配置 9.4.1 原理概述 OSPF被动接口也称抑制接口&#xff0c;成为被动接口后&#xff0c;将不会接收和发送OSPF报文。如果要使OSPF路由信息不被某一网络中的路由器获得且使本地路由器不接收网络中其他路由器发布的路由更新信息&#xff0c;即已运行在OSPF协议…

【泛微系统】解决启动非标功能时提示客户ID不一致的问题

解决启动非标时提示CID不一致的问题 泛微OA系统是一个非常丰富的系统,我们在日常工作中会经常遇到很多业务需求,我们会用到很多功能来承载这些需求的实现;OA系统里有标准功能,也有非标准的功能;对于非标准的功能需要打非标补丁包; 有些同学在个人学习系统的过程中会安装本…

[图解]企业应用架构模式2024新译本讲解16-行数据入口2

1 00:00:00,750 --> 00:00:02,470 好&#xff0c;我们来看代码 2 00:00:03,430 --> 00:00:06,070 我们一步一步执行 3 00:00:42,500 --> 00:00:45,000 先初始化数据 4 00:00:52,300 --> 00:00:53,650 创建连接 5 00:00:55,900 --> 00:00:56,970 这里面 6 0…

Electron快速入门(二):在(一)的基础上修改两个文件完成自定义显示时间和天气的标题栏

修改主进程:main.js // main.jsconst { app, BrowserWindow } = require("electron"); const path = require("node:path"); const createWindow = () => {try {const mainWindow = new BrowserWindow({width: 1200,height: 870,alwaysOnTop: true,fr…

aws的alb,多个域名绑定多个网站实践

例如首次创建的alb负载均衡只有www.xxx.com 需要添加 负载 test2.xxx.com aws的Route 53产品解析到负载均衡 www.xxx.com 添加CNAME&#xff0c;到负载均衡的dns字段axx test2.xxx.com 添加CNAME&#xff0c;到负载均衡的dns字段axx 主要介绍目标组和规则 创建alb就不介…

【报错解决】引入@ComponentScan注解注册bean容器后,导致的接口404问题

引入ComponentScan注解注册bean容器后&#xff0c;导致的接口404问题 背景 由于微服务开发中&#xff0c;经常需要在公共模块在引入一些公共模块&#xff0c;供其他服务使用&#xff0c;但是其他服务需要在启动类中配置ComponentScan注解扫描这个公共模块下注册的 bean&#…

sdlan如何智能组网?

【天联】组网是一款异地组网内网穿透产品&#xff0c;由北京金万维科技有限公司自主研发&#xff0c;旨在解决不同地区电脑与电脑、设备与设备、电脑与设备之间的信息远程通信问题。【天联】的操作简单、跨平台应用、无网络要求以及独创的安全加速方案等特点&#xff0c;使得它…

全国实体商铺店铺商家采集工具,一键采集商家手机号,让你轻松找到目标客户

随着互联网的发展&#xff0c;越来越多的商家开始在网上开展业务&#xff0c;实体商铺的竞争也日益激烈。为了更好地吸引客户&#xff0c;很多商家都选择了线上推广和营销。然而&#xff0c;仅仅依靠线上推广是远远不够的&#xff0c;线下的实体商铺也需要积极拓展客源。因此&a…

C语言学习记录20240622

这次需要用 C 语言库 Allegro 写爆破彗星游戏。项目有一些描述如需要绘制飞船、彗星、子弹&#xff0c;需要响应按键实现飞船加速、减速、转向、开火&#xff0c;需要绘制弹道&#xff0c;需要实现彗星旋转、缩放&#xff0c;需要碰撞检测&#xff0c;需要显示计分。 这些用 w…

Docker 搭建 MinIO 对象存储

Docker 搭建 MinIO 对象存储 一、MinIO MinIO 是一个高性能的对象存储服务器&#xff0c;用于构建云存储解决方案。MinIO 允许你存储非结构化数据&#xff08;如图片、视频、日志文件等&#xff09;以对象的形式。MinIO 提供简单的部署选项和易于使用的界面&#xff0c;允许你…

高校新闻头条系统

摘 要 随着互联网技术的快速发展&#xff0c;网络几乎成为了人们搜集信息和交流沟通最方便、快捷的通道&#xff0c;科技创新一直在影响着人们的生活&#xff0c;人们的衣食住行也在不断变化&#xff0c;与此同时&#xff0c;也大大改变了人们获取信息的方式&#xff0c;人们获…

如何恢复 Mac 数据?适用于 Mac 的免费磁盘恢复软件

对于大多数 Mac 电脑用户来说&#xff0c;丢失数据是他们最不想遇到的噩梦之一。然而&#xff0c;无论我们多么小心地使用 Mac&#xff0c;多么有条理地存储重要文件&#xff0c;我们仍然有可能丢失 Mac 上的数据。某些硬件故障更有可能导致您意外丢失文件。除此之外&#xff0…

Camtasia2024中文版最新电脑录屏剪辑神器!

大家好&#xff0c;今天我要安利一个我最近超级喜欢的工具——Camtasia2024中文版&#xff01;这款软件真的太棒了&#xff0c;它让我的视频编辑工作变得更加轻松和高效。如果你也对视频制作感兴趣&#xff0c;那么一定要尝试一下这款神器哦&#xff01; Camtasia2024win-正式…

Android基于MediaBroswerService的App实现概述

mSession.setPlaybackState(mStateBuilder.build()); // 5. 关联 SessionToken setSessionToken(mSession.getSessionToken()); } } 根据包名做权限判断之后&#xff0c;返回根路径 Override public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundl…

论文解读:Pandora: 朝着结合自然语言动作与视频状态的通用世界模型发展

论文《Pandora: 朝着结合自然语言动作与视频状态的通用世界模型发展》探索了构建一个高度集成的AI系统&#xff0c;旨在理解自然语言指令并在视频所代表的视觉环境中执行相应操作&#xff0c;从而推进对复杂动态场景的建模与预测能力。以下是该论文的关键点和贡献的详细解读&am…