pnpm、yarn和npm三者的特性和区别

433 阅读6分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第18天,点击查看活动详情

一、前言

最近在查资料的时候,总是无意间就能看到pnpm的字眼,心想着npm和yarn我知道,也用过,但是没见过pnpm啊,这是个啥子玩意儿,于是乎我就一个劲儿地追问度娘,才略微搞明白了一点,下面我就献丑给大家伙讲讲这三者的特性。

二、npm

1、基础知识

npm的设计思想是语义版本控制,每个版本号都分为

主版本号.次版本号.补丁版本号

什么时候需要增加相应版本号

主版本号: 大版本号,即api发生改变了,并且与之前的版本不兼容
次版本号: 增加功能了,但是向后版本兼容了
补丁版本号: 上述向后兼容存在缺陷,并且被修复了

npm是用package.json来管理包依赖的,比如下面这里package.json里的dependencies的代码,

在我运行 npm install better-scroll时,就会自动生成

"dependencies": {
    "better-scroll": "^2.4.2"
}

意思是按照了better-scroll依赖,注意这里在主版本号前有^号,这里是告诉npm,只需要按照主版本号为2的任意版本就行,如果没加^号,就指定按照这个版本。

2、特性

npm的嵌套依赖十分出名,包与包之间存在很严重的依赖关系。

我举个例子,我们现在使用npm2,然后需要引入a包,然后a包依赖于b包,b包又依赖于c包,层层嵌套,那依赖包的结构就是下图这样

node_modules
- package-A 
-- node_modules
--- package-B 
----- node_modules 
------ package-C
-------- 可能名字很长的具体文件.js

这里只是举例一下,实际情况比这更加常见和糟糕,为什么说糟糕呢,是因为当文件路径名过长(超过260个字符左右吧),window系统大概率处理不了。

如果是npm3,那么针对这个问题已经处理过了,npm3会生成扁平化结构,结构会变成下面这样。

node_modules
- package-A 
- package-B 
- package-C
-- 可能名字很长的具体文件在c包里面.js

这样的情况下,文件路径名就不会出现过长的情况,但是这也是有前提的,npm3生成这样的扁平化,它需要先遍历一遍所有的项目依赖关系,这是一项非常耗时的操作,也是造成npm安装缓慢的主要原因。

不过npm是有本地缓存的说法的,可以用以下命令查看已缓存的包

 npm cache ls

这种设计也有助于减少npm安装包的时间的,有用但不多。

同时用package.json来管理包,也存在版本不确定的问题,因为各种嵌套,就可能发生a包和b包同时依赖了c包的不同版本,那这种情况下到底是要安装c包的哪个版本还存在疑问。

npm出了个命令

 npm shrinkwrap

可以生成一个npm-shrinkwrap.json文件,会记录所有包和所有嵌套包记录好确切的版本,但是这种也只能锁定包的版本,对于包版本内容发生改变,npm也无能为力。

但整体来说,npm还是一个比较成熟、稳定的包管理器。

三、yarn

1、基础知识

yarn发布于2016年10号,在github上目前拥有4w颗star,而更早发布的npm目前才1.7w颗star。从这里就知道两者哪个更受欢迎了。

上面我们说到了npm存在,嵌套严重,无法保证依赖包版本的问题,yarn就是为了解决这些问题而出现的。

yarn的用法和npm基本相同,命令上有些许区别

npmyarn
npm installyarn
npm install vue -saveyarn add vue
npm uninstall vue -saveyarn remove vue
npm install vue -save--devyarn remove vue -dev
npm update –saveyarn upgrade

2、特性

yarn可以做到以下几点

(1) 确定性

不管安装顺序如何,相同的依赖关系将在每台机器上以相同的方式安装。

(2) 网络性能

Yarn 有效地对请求进行排队处理,避免发起的请求如瀑布般倾泻,以便最大限度地利用网络资源。

(3) 相同的软件包

从 npm 安装软件包并保持相同的包管理流程。

(4) 网络弹性

重试机制确保单个请求失败并不会导致整个安装失败。

(5) 扁平模式

将依赖包的不同版本归结为单个版本,以避免创建多个副本。比npm3更快。

(6) 离线模式

如果你以前安装过某个包,再次安装时可以在没有任何互联网连接的情况下进行。这可是npm目前都没实现的功能。

凭这几点,就基本完爆npm。

这里插一句笑谈,刚开始yarn作为新生代,官网是这么说的

*最简单的入门方法是通过npm安装:

npm install -g yarn

yarn*

然后现在硬气了,官网改说法了

 注意:通常情况下不建议通过npm进行安装。npm安装是非确定性的,程序包没有签名,
 并且npm除了做了基本的SHA1哈希之外不执行任何完整性检查,这给安装系统程序带来
 了安全风险。基于这些原因,强烈建议你通过最适合于你的操作系统的安装方法来安装yarn。

不过针对的好,以前npm一家独大,对于用户反馈的bug,爱答不理的。现在有竞争了,才能更好激发npm的进步意思。

四、pnpm

1、基础知识

pnpm全称,performant npm ,意味“高性能的 npm”。pnpm由npm/yarn衍生而来,但是它解决了npm/yarn可能隐含的bug,同时还优化了性能,扩宽使用场景,有最先进的包管理者之称。

2、特性

(1) 依赖管理

pnpm依赖策略,采用和yarn/npm3一样的消除依赖提升,同时还规范了拓补结构。

(2) 存储管理

pnpm是按内容寻址的,采用硬链接和符号链接所有的本地缓存源文件,yarn的话是直接复制的, 一个内容寻址,一个复制内容,可想而知,这就是pnpm运行为什么比yarn还快的原因。

(3) 安全性

npm/yarn都存在这个问题,比如a包依赖b包,b包依赖c包,那可能造成非法访问的情况: a包直接用c包,但a包中并没有声明c包。

不过pnpm 自创了一套依赖管理方式来解决了这个问题,保证了安全性。

(4)离线模式和确定性

pnpm继承了yarn的优点,离线模式和确定性安装。

3、安装使用

全局安装

 npm i pnpm -g
 

切换源

  pnpm config get registry //查看源
  pnpm config set registry https://registry.npmmirror.com //切换淘宝源

直接进入到项目里,可以使用下面命令,安装依赖和运行,用法和npm一致

 pnpm install
 pnpm run dev

五、总结

我认为npm胜在时间久,有着大量的测试用例,能有效提供解决方案。 而yarn和pnpm的出现也是必然,时代会进步,npm存在的不足,npm如果不解决,自然会有别人(yarn和pnpm)处理,有竞争才会有进步。如果大家伙平时一直用npm,那有机会可以试试yarn和pnpm,可能会有不一样的体验呢。

ps: 我是地霊殿__三無,希望文章能对大家有所帮助。

Snipaste_2022-07-19_15-30-26.jpg