pnpm是 Node.js 的替代包管理器。它是 npm 的直接替代品,但速度更快、效率更高。
为什么更有效率?当你安装一个包时,我们将它保存在你电脑上的全局存储中,然后我们从它创建一个硬链接而不是复制。也就是说:对于模块的每个版本,磁盘上只保留一份副本。例如,当使用 npm 或 yarn 时,如果您有 100 个使用 lodash 的包,您将在磁盘上拥有 100 个 lodash 副本。Pnpm 可以让你节省千兆字节的磁盘空间!
为什么不是 yarn ?
事实上 yarn 只是对 npm 的一个小改进。尽管它使安装速度更快并且具有一些不错的新功能,但它却使用了和 npm 相同的扁平化 node_modules 结构。
扁平化的 node_modules 结构带来了很多问题:
1.模块可以访问它们不依赖(没有进行声明)的包 (这极其不合理!)
2.扁平化依赖的算法非常复杂
3.一些包必须复制到一个项目的 node_modules 文件夹中(太浪费空间了!)
截至目前,pnpm 具有 yarn 优于 npm 的所有优点(是的,是所有):
1.安全: 与 Yarn 一样,pnpm 有一个特殊文件,其中包含所有已安装包的校验和,用于在执行其代码之前验证每个已安装包的完整性。
2.离线模式: pnpm 将所有下载的包 tarball 保存在本地注册表镜像中。当包在本地可用时,它从不发出请求。使用该--offline
参数,可以完全禁止HTTP 请求。
3.速度: pnpm 不仅比 npm 快,而且比 Yarn 快。无论是冷缓存还是热缓存,它都比 Yarn 快。Yarn 从缓存中复制文件,而 pnpm 只是从全局存储中链接它们。
为什么?
正如我之前提到的,pnpm 不会扁平化依赖结构。因此,pnpm 使用的算法可以简单很多。
那么 pnpm 如何构建 node_modules 目录,而不是通过扁平化它呢?要理解它,我们应该回忆一下 node_modules 文件夹在 npm@3 之前的样子。在 npm@3 之前,node_modules 结构是可预测的,因为 node_modules 中的每个依赖项都有自己的 node_modules 文件夹,其中指定了所有依赖项包 .json 。
node_modules
└─ foo ├─ index.js ├─ package.json └─ node_modules└─ bar ├─ index.js └─ package.json
这种方法有两个严重的问题:
- 包经常创建太深的依赖树,这导致 Windows 上的目录路径过长(直到出错)
- 当在不同的依赖项中需要时,包被复制粘贴了几次
为了解决这些问题,npm 重新考虑了 node_modules 结构并提出了扁平化。使用 npm@3 , node_modules 结构现在看起来像这样:
node_modules
├─ foo
|├─ index.js
|└─ package.json
└─ bar ├─ index.js └─ package.json
与 npm@3 不同,pnpm 试图解决 npm@2 存在的问题,而不扁平化依赖树。在 pnpm 创建的 node_modules 文件夹中,所有包都有自己的依赖项组合在一起,但目录树永远不会像 npm@2 那样深。pnpm 保持所有依赖关系平坦,但使用软连接将它们组合在一起。
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
虽然这个例子对于一个小项目来说似乎太复杂了,但对于更大的项目来说,这个结构看起来比 npm/yarn 创建的结构更好。让我们看看它为什么有效。
首先,你可能已经注意到, node_modules 根目录中的包只是一个符号链接。这很好,因为 Node.js 会忽略符号链接并执行真实路径。
其次,所有已安装的包在其目录中都没有自己的 node_modules 文件夹。那么 foo 怎么找到 bar 呢?让我们看一下包含 foo 包的文件夹:
node_modules/.registry.npmjs.org/foo/1.0.0/node_modules
├─ bar -> ../../bar/2.0.0/node_modules/bar
└─ foo ├─ index.js └─ package.json
如你看到的:
1.foo 的依赖项在目录结构中更上一层。
2.这两个包都在 *node_modules 文件夹中
foo 可能需要 bar,因为 Node.js 在目录结构中查找模块直到磁盘的根目录。foo 也可以 require foo,因为它就在 node_modules 中。
尝试一下吧
你只需要通过 npm 安装 pnpm:执行 npm install -g pnpm
。这样以后就不需要用 npm 啦。
最后
整理了一套《前端大厂面试宝典》,包含了HTML、CSS、JavaScript、HTTP、TCP协议、浏览器、VUE、React、数据结构和算法,一共201道面试题,并对每个问题作出了回答和解析。
有需要的小伙伴,可以点击文末卡片领取这份文档,无偿分享
部分文档展示:
文章篇幅有限,后面的内容就不一一展示了
有需要的小伙伴,可以点下方卡片免费领取