pnpm与npm和yarn的区别

作为一名前端程序员,对npmyarn这两个包管理器一定不陌生,那么你听说过pnpm么?它到底是个什么东西?和npm还有yarn有什么区别,又有什么作用呢?本文就将解决以下这几个问题:

  1. pnpm是什么?有什么作用
  2. pnpm有什么优势和特点
  3. pnpmnpmyarn有什么不同?
  4. pnpm如何安装和使用

1.pnpm是什么 

快速的,节省磁盘空间的包管理工具

通过pnpm的简介我们可以看出来它实际上就是一个包管理工具,作用是跟npmyarn一样的呢。那既然功能是一样的为什么又要出现一个pnpm呢?通过官方的文档我们可以看出来它的优势在于:

  • 包安装速度极快
  • 磁盘空间利用效率高

 2.pnpm有什么优势和特点

我们上面提到了pnpm的优势在于包安装速度极快磁盘空间利用效率高

包安装速度极快

比传统方案安装包的速度快了两倍,以下是官方给出的benchmarks(对比了npm, pnpm, Yarn Classic, and Yarn PnP),在多种常见情况下,执行install的速度比较

为什么pnpm要比其他的包处理器要快呢?

主要得益于它的包管理机制,实现了节约磁盘空间并提升安装速度(也就是第二个优势)

 磁盘空间利用效率高

pnpm 的 node_modules 布局使用符号链接来创建依赖项的嵌套结构。node_modules 中每个包的每个文件都是来自内容可寻址存储的硬链接。

那么为什么说pnpm这种基于内容寻址的方式对磁盘空间利用效率比较高呢

  • 不会重复安装同一个包。使用npm/yarn 的时候,如果100个包依赖express ,那么就可能安装了100次express ,磁盘中就有100个地方写入了这部分代码。但是pnpm会只在一个地方写入这部分代码,后面使用会直接使用硬链接

 

  • 即使一个包的不同版本,pnpm 也会极大程度地复用之前版本的代码。举个例子,比如 express4.18.2 和epxress5.0.0-beta.1的两个版本升级对比,epxress5.0.0-beta.1只是重新下载了19个新的更新的包。

 

3. pnpmnpmyarn有什么不同?

pnpmnpmyarn的不同点主要是从包的依赖管理方面来说明。

npm2的依赖管理

npm2生成的依赖管理比较的简单直接,会按照安装包的依赖树形结构直接填充在本地的目录结构下: 

 npm2的这种方式的优点就是比较的直观,但是呢缺点也是显而易见的就是

  1. 层级依赖过深
  2. 相同包的相同版本会多次被下载,利用率低,占用磁盘空间大

npm3/yarn依赖管理 

针对npm2的两个缺点呢,npm3做了个改变,不再使用嵌套的结构了,而是讲依赖进行打平,这样就能解决层级依赖深和包的利用率的问题,那么上面的依赖关系就会变成下面这个样子:

 

在文件里看就是下面的这个样子 

 

我们可以看出,[email protected][email protected]引用了accepts的版本是一样的,这样才会被平铺在node_modules下,那如果引用的包的版本不一样又是什么样的情况呢?就像debug,http-errorsstatuses等这几个包

此时,在node_modules结构是下面这个样子: 

 

 

 至于为什么说[email protected]的依赖包会在根目录的node_modules下呢,这是npm自己的一个规则,

npm从3.x开始,采用了扁平化的方式来安装node_modules。在安装时,npm会遍历整个依赖树,不管是项目的直接依赖还是子依赖的依赖,都会优先安装在根目录的node_modules中。遇到相同名称的包,如果发现根目录的node_modules中存在但是不符合semver-range,会在子依赖的node_modules中安装符合条件的包。

npm3的这种平铺方式确实是解决了层级依赖深和包的利用率的问题,但是也引入了其他的问题:

  • 对没有手动引入的包,例如[email protected]依赖的cookie,项目中手动引入,但是依然可以使用,这样就造成了如果哪天express改变了策略不在使用cookie,而我们的项目中又使用了cookie,这样就会导致项目无法启动
  • 虽然npm是共享了相同版本的依赖,但是如果版本不同,npm还是会完整的下载两个不同的版本,这样也会有依赖的冗余

 pnpm为了解决npm3带来的一些问题呢,采用了另外一种方式来管理依赖:pnpm 的 node_modules 布局使用符号链接来创建依赖项的嵌套结构管。

node_modules 中.pnpm下每个包的每个文件都是来自内容可寻址存储的硬链接。

这是 node_modules 中的唯一的“真实”文件。 一旦所有包都硬链接到 node_modules,就会创建符号链接来构建嵌套的依赖关系图结构。

我们用pnpm安装一下[email protected][email protected],生成的目录如下所示:

node_modules中的依赖只有在package.json中手动引入的依赖expresskoa,细心的你会发现这两个文件后面有一个箭头,而这个箭头就是pnpm使用的软连接的方式指向了.pnpm文件真正的文件: 

 

 这些文件会在内存中统一存储,如果有依赖不同版本的时候,pnpm也只会下载不同版本中不同的有差异的文件添加到仓库(store)。

例如,如果某个包有100个文件,而它的新版本只改变了其中1个文件。那么 pnpm update 时只会向存储中心额外添加1个新文件,而不会因为仅仅一个文件的改变复制整新版本包的内容。

所有文件都会存储在硬盘上的某一位置。

当软件包被被安装时,包里的文件会硬链接到这一位置,而不会占用额外的磁盘空间这允许你跨项目地共享同一版本的依赖。

安装使用

npm install -g pnpm

Command Meaning
pnpm add sax 保存到 dependencies
pnpm add -D sax 保存到 devDependencies
pnpm add -O sax 保存到 optionalDependencies
pnpm add -g sax Install package globally
pnpm add sax@next 从 next 标签下安装
pnpm add [email protected] 安装指定版本 3.0.0

 下载依赖

pnpm install or pnpm i

删除依赖 

pnpm remove or pnpm rm or pnpm uninstall or pnpm un 

猜你喜欢

转载自blog.csdn.net/Javahtml12/article/details/131600319