Why should we use pnpm?
pnpm 是Node.js的替代软件包管理器。它是npm的直接替代品,但速度更快,效率更高。
快到多少倍呢?结论是3倍;
为什么效率更高?当您安装软件包时,我们会将其保存在计算机上的全局存储中,然后我们从中创建硬链接,而不是进行复制。对于模块的每个版本,磁盘上仅保留一个副本。例如,当使用npm或yarn时,如果有100个使用lodash的软件包,则磁盘上将有100个lodash副本。 Pnpm可以节省千兆字节的磁盘空间
为什么现在不使用yarn?
与npm相比,Yarn只是一个小改进。尽管它使安装速度更快并且具有一些不错的新功能,但它使用的组件与npm相同的扁平node_modules结构(自版本3起)
而且扁平化的包会导致一系列的问题,例如
- 模块可以访问不依赖的程序包
- 展平依赖树的算法非常复杂
- 有些软件包必须复制到一个项目的node_modules文件夹中
而且yarn并没有计划去解决占用磁盘空间依赖大的问题,所以我们更应该关注pnpm新的依赖包,截止到现在,pnpm有超过npm的所有功能
- 安全。像Yarn一样,pnpm具有一个特殊文件,其中包含所有已安装软件包的校验和,以在执行其代码之前验证每个已安装软件包的完整性
- 离线模式。 pnpm将所有下载的程序包tarball保存在本地注册表镜像中。当程序包在本地可用时,它永远不会发出请求。使用--offline参数,可以完全禁止HTTP请求。
- 速度。 pnpm不仅比npm快,而且比Yarn快。无论是冷缓存还是热缓存,它都比Yarn快。 Yarn从缓存中复制文件,而pnpm只是从全局存储中链接它们。
目前的npm的使用模式是: node_modules中的每个依赖项都有其自己的node_modules文件夹,并且其所有依赖项都在package.json中指定,因此node_modules的结构是这样的
node_modules
└─ foo
├─ index.js
├─ package.json
└─ node_modules
└─ bar
├─ index.js
└─ package.json
这就会导致两个问题:
- 程序包经常创建过深的依赖树,从而导致Windows上的长目录路径问题
- 在不同依赖项中需要时,将软件包复制粘贴几次 为了解决此问题,npm3进行了扁平化处理
node_modules
├─ foo
| ├─ index.js
| └─ package.json
└─ bar
├─ index.js
└─ package.json
pnpm是这样处理的,如下 在由pnpm创建的node_modules文件夹中,所有软件包都将自己的依赖项分组在一起,但是目录树的深度从来没有npm @ 2这么深。 pnpm使所有依赖项保持平坦,但使用符号链接将它们分组在一起;
说人话就是跟原npm一样,通过硬连接链接所需的包而不是所有模块下都安装自己的的依赖
-> - a symlink (or junction on Windows)
node_modules
├─ foo -> .registry.npmjs.org/foo/1.0.0/node_modules/foo
└─ .registry.npmjs.org
├─ foo/1.0.0/node_modules
| ├─ bar -> ../../bar/2.0.0/node_modules/bar
| └─ foo
| ├─ index.js
| └─ package.json
└─ bar/2.0.0/node_modules
└─ bar
├─ index.js
└─ package.json
这个是示例: 示例sample-project
- 首先,您可能已经注意到,node_modules根目录中的包只是一个符号链接。这很好,因为Node.js会忽略符号链接并执行真正的路径
- 其次,没有一个已安装的软件包在其目录内有其自己的node_modules文件夹。
node_modules/.registry.npmjs.org/foo/1.0.0/node_modules
├─ bar -> ../../bar/2.0.0/node_modules/bar
└─ foo
├─ index.js
└─ package.json
我们的使用方式为:npm install -g pnpm
综上所述:个人是这样觉得
- pnpm运行起来非常的快,超过了npm和yarn
- pnpm采用了一种巧妙的方法,利用硬链接和符号链接来避免复制所有本地缓存源文件,这是yarn和npm的最大的性能弱点之一
- 使用链接并不容易,好多人不了解或者还存在其他问题。
- pnpm继承了yarn的所有优点,包括离线模式和确定性安装
- 其次pnpm可能在一些自身开发的小型项目中使用,逐步过渡到大型项目中进行验证。