为什么我们应该使用pnpm?
1. 前言
Author: Zoltan Kochan
译者:philoenglish.com 团队
关键字: pnpm, npm, yarn
pnpm是 Node.js 的替代包管理器。它是 npm 的直接替代品,但速度更快、效率更高。
多快?快3倍!请参阅此处的基准。
为什么效率更高?当您安装软件包时,我们将其保存在您计算机上的全局存储中,然后我们从中创建硬链接而不是复制。对于模块的每个版本,磁盘上仅保留一个副本。例如,当使用npm或yarn时,如果您有100个使用lodash的包,则磁盘上将有100个lodash副本。Pnpm 可以让您节省千兆字节的磁盘空间!
2. 为什么不使用yarn?
说实话,当 Yarn 公开时我真的很失望。几个月来我为 pnpm 做出了大量贡献,却没有任何关于 Yarn 的消息。有关其开发的信息并未公开。
几天后,我意识到 Yarn 只是对 npm 的一个小小的改进。尽管它使安装速度更快并且具有一些不错的新功能,但它使用与 npm 相同的扁平node_modules结构(自版本 3 以来)。
扁平化的依赖树会带来一系列问题:
- 模块可以访问它们不依赖的包
- 展平依赖树的算法非常复杂
- 某些包必须复制到一个项目的node_modules文件夹中
此外,还有一些 Yarn 不打算解决的问题,例如磁盘空间使用问题。所以我决定继续投入时间到 pnpm,并取得了巨大的成功。截至目前(2017 年 3 月),pnpm 拥有 Yarn 相对于 npm 的所有附加功能:
- 安全。与 Yarn 一样,pnpm 有一个特殊文件,其中包含所有已安装包的校验和,用于在执行每个已安装包的代码之前验证其完整性。
- 离线模式。pnpm 将所有下载的软件包 tarball 保存在本地注册表镜像中。当包在本地可用时,它从不发出请求。通过该–offline参数,可以完全禁止HTTP请求。
- 速度。pnpm 不仅比 npm 快,而且比 Yarn 快。无论是冷缓存还是热缓存,它都比 Yarn 更快。Yarn 从缓存中复制文件,而 pnpm 只是从全局存储中链接它们。
3. 这是如何成为可能的
正如我之前提到的,pnpm 不会展平依赖关系树。这样一来,pnpm 使用的算法就可以简单很多!这就是为什么可能只有 1 名开发人员就能跟上数十名 Yarn 贡献者的步伐。
那么,如果不是通过扁平化,pnpm 是如何构建node_modules目录的呢?为了理解它,我们应该回顾一下npm 版本 3 之前的node_modules文件夹是什么样子的。在npm@3之前,node_modules结构是可预测且干净的,因为node_modules中的每个依赖项都有自己的node_modules文件夹,其中指定了所有依赖项包.json。
1 | node_modules |
这种方法有两个严重的问题:
包经常创建太深的依赖树,这导致 Windows 上的长目录路径问题
当不同的依赖项需要包时,它们会被复制粘贴多次
为了解决这些问题,npm 重新思考了node_modules结构并提出了扁平化。使用npm@3 ,node_modules结构现在如下所示:
1 |
|
有关 npm v3 依赖项解析的更多信息,请参阅npm v3 依赖项解析。
与 npm@3 不同,pnpm 尝试解决 npm@2 存在的问题,而不压平依赖关系树。在pnpm 创建的node_modules文件夹中,所有包都有自己的依赖项分组在一起,但目录树永远不会像 npm@2 那样深。pnpm 保持所有依赖关系平坦,但使用符号链接将它们分组在一起。
1 |
|
要查看实时示例,请访问示例 pnpm 项目存储库。
尽管该示例对于小型项目来说似乎过于复杂,但对于较大的项目,该结构看起来比 npm/yarn 创建的结构更好。让我们看看它为什么有效。
首先,您可能已经注意到,node_modules根目录中的包只是一个符号链接。这很好,因为 Node.js 会忽略符号链接并执行真实路径。因此require(‘foo’)将执行该文件node_modules/.registry.npmjs.org/foo/1.0.0/node_modules/foo/index.js 而不是node_modules/foo/index.js
其次,所有已安装的软件包的目录中都没有自己的node_modules文件夹。那么foo如何require bar呢?让我们看一下包含foo包的文件夹:
1 |
|
如你看到的
foo(只是bar )的依赖项已安装,但在目录结构中上一层。
这两个包都位于名为node_modules的文件夹中
foo可以require bar,因为 Node.js 在目录结构中查找模块,直到磁盘的根目录。并且foo也可以 require foo,因为它位于名为node_modules的文件夹中 (是的,这就是某些包所做的)。
4. 您是否会使用pnpm?
如果我的观点说服了, 并打算使用pnpm.
只需通过 npm: 安装 pnpm 即可npm install -g pnpm
。每当你想安装某些东西时,请使用它而不是 npm:pnpm i foo
。
您还可以在pnpm GitHub 存储库或pnpm.js.org阅读更多信息。您可以在 Twitter 上关注pnpm on Twitter或在pnpm Gitter 聊天室寻求帮助。
5. Nodejs 系列文章
最新更新以及更多Nodejs相关文章请访问 鹏叔的技术博客 - Nodejs
6. 参考文章
为什么我们应该使用pnpm?