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源码解读

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

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

相关文章

DS1339C串行实时时钟-国产兼容RS4C1339

RS4C1339串行实时时钟是一种低功耗的时钟/日期设备,具有两个可编程的一天时间报警器和一个可编程方波输出。地址和数据通过2线双向总线串行传输。时钟/日期提供秒、分钟、小时、天、日期、月份和年份信息。对于少于31天的月份,月末的日期会自动调整&…

SpringBootWeb 篇-入门了解 Vue 前端工程的创建与基本使用

🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 基于脚手架创建前端工程 1.1 基于 Vue 开发前端项目的环境要求 1.2 前端工程创建的方式 1.2.1 基于命令的方式来创建前端工程 1.2.2 使用图形化来创建前端工程 1.…

OpenCV机器学习-人脸识别

一 基本概念 1 计算机视觉与机器学习的关系 计算机视觉是机器学习的一种应用,而且是最有价的应用。 2 人脸识别 哈尔(haar)级联方法 Harr是专门为解决人脸识别而推出的; 在深度学习还不流行时,Harr已可以商用; 深度学习方法&am…

Springboot微服务整合缓存的时候报循环依赖的错误 两种解决方案

错误再现 Error starting ApplicationContext. To display the conditions report re-run your application with debug enabled. 2024-06-17 16:52:41.008 ERROR 20544 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPLI…

【chatgpt】train_split_test的random_state

在使用train_test_split函数划分数据集时,random_state参数用于控制随机数生成器的种子,以确保划分结果的可重复性。这样,无论你运行多少次代码,只要使用相同的random_state值,得到的训练集和测试集划分就会是一样的。…

【Git】win本地 git bash:Connect reset by 20.205.243.166 port22报错问题解决

win10 git bash 控制台 reset 22端口拒绝连接问题: Connection reset by 20.205.243.166 port 221、22端口 无法连接 ssh -T gitgithub.com2、尝试用443端口 仍然无法连接 ssh -T -P 443 gitgithub.com3、重写 git clone 地址 url,全局添加 https 前缀…

【jenkins1】gitlab与jenkins集成

文章目录 1.Jenkins-docker配置:运行在8080端口上,机器只要安装docker就能装载image并运行容器2.Jenkins与GitLab配置:docker ps查看正在运行,浏览器访问http://10....:8080/2.1 GitLab与Jenkins的Access Token配置:不…

如何关闭软件开机自启,提升电脑开机速度?

如何关闭软件开机自启,提升电脑开机速度?大家知道,很多软件在安装时默认都会设置为开机自动启动。但是,有很多软件在我们开机之后并不是马上需要用到的,开机启动的软件过多会导致电脑开机变慢。那么,如何关…

Cesium如何高性能的实现上万条道路的流光穿梭效果

大家好,我是日拱一卒的攻城师不浪,专注可视化、数字孪生、前端、nodejs、AI学习、GIS等学习沉淀,这是2024年输出的第20/100篇文章; 前言 在智慧城市的项目中,经常会碰到这样一个需求:领导要求将全市的道路…

SCI一区级 | Matlab实现BO-Transformer-LSTM多变量时间序列预测

SCI一区级 | Matlab实现BO-Transformer-LSTM多变量时间序列预测 目录 SCI一区级 | Matlab实现BO-Transformer-LSTM多变量时间序列预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.【SCI一区级】Matlab实现BO-Transformer-LSTM多变量时间序列预测,贝叶斯…

分布式,容错:10台电脑坏了2台

由10台电脑组成的分布式系统,随机、任意坏了2台,剩下的8台电脑仍然储存着全部信息,可以继续服务。这是怎么做到的? 设N台电脑,坏了H台,要保证上述性质,需要有冗余,总的存储量降低为…

【Flink metric】Flink指标系统的系统性知识:以便我们实现特性化数据的指标监控与分析

文章目录 一. Registering metrics:向flink注册新自己的metrics1. 注册metrics2. Metric types:指标类型2.1. Counter2.2. Gauge2.3. Histogram(ing)4. Meter 二. Scope:指标作用域1. User Scope2. System Scope ing3. User Variables 三. Reporter ing四. System m…

华为数通——单臂路由

单臂路由:指在三层设备路由器的一个接口上通过配置子接口(或“逻辑接口”,并不存在真正物理接口)的方式,实现原来相互隔离的不同VLAN(虚拟局域网)之间的互联互通。但是仅仅允许单播通信。 单臂路…

Web3新视野:Lumoz节点的潜力与收益解读

摘要:低估值、高回报、无条件退款80%...... Lumoz正通过其 zkVerifier 节点销售活动,引领一场ZK计算革命。 长期以来,加密市场以其独特的波动性和增长潜力,持续吸引着全球投资者的目光。而历史数据表明,市场往往在一年…

示例:WPF中应用DependencyPropertyDescriptor监视依赖属性值的改变

一、目的:开发过程中,经常碰到使用别人的控件时有些属性改变没有对应的事件抛出,从而无法做处理。比如TextBlock当修改了IsEnabled属性我们可以用IsEnabledChanged事件去做对应的逻辑处理,那么如果有类似Background属性改变我想找…

vscode用vue框架2,续写登陆页面逻辑,以及首页框架的搭建

目录 前言: 一、实现登录页信息验证逻辑 1.实现登录数据双向绑定 2.验证用户输入数据是否和默认数据相同 补充知识1: 知识点补充2: 二、首页和登录页之间的逻辑(1) 1. 修改路由,使得程序被访问先访问首页 知识点补充3&am…

一、系统学习微服务遇到的问题集合

1、启动了nacos服务&#xff0c;没有在注册列表 应该是版本问题 Alibaba-nacos版本 nacos-文档 Spring Cloud Alibaba-中文 Spring-Cloud-Alibaba-英文 Spring-Cloud-Gateway 写的很好的一篇文章 在Spring initial上面配置 start.aliyun.com 重新下载 < 2、 No Feign…

【Java】Java基础语法

一、注释详解 1.1 注释的语法&#xff1a; // 单行注释/*多行注释 *//**文档注释 */ 1.2 注释的特点&#xff1a; 注释不影响程序的执行&#xff0c;在Javac命令进行编译后会将注释去掉 1.3 注释的快捷键 二、字面量详解 2.1 字面量的概念&#xff1a; 计算机是用来处理…

西木科技Westwood-Robotics人型机器人Bruce配置和真机配置

西木科技Westwood-Robotics人型机器人Bruce配置和真机配置 本文内容机器人介绍Bruce机器人Gazebo中仿真代码部署Bruce真机代码部署 本文内容 人形机器人Brcue相关介绍docker中安装Gazebo并使用Bruce机器人控制器更换环境配置 机器人介绍 公司&#xff1a;西木科技Westwood-R…

「动态规划」如何求环绕字符串中唯一的子字符串个数?

467. 环绕字符串中唯一的子字符串https://leetcode.cn/problems/unique-substrings-in-wraparound-string/description/ 定义字符串base为一个"abcdefghijklmnopqrstuvwxyz"无限环绕的字符串&#xff0c;所以base看起来是这样的&#xff1a;"...zabcdefghijklm…