当前位置:首页 > 前端开发 > 正文内容

pnpm 是怎么推翻 npm 和 yarn 的?

邻居的猫1个月前 (12-09)前端开发1987

今日研讨了一下 pnpm 的机制,发现它的确很强壮,乃至能够说对 yarnnpm 形成了降维冲击 。

咱们从包办理工具的开展前史,一同看下究竟好在哪里?

npm2

在 npm 3.0 版别之前,项目的 node_modules 会呈现出嵌套结构,也便是说,我装置的依靠、依靠的依靠、依靠的依靠的依靠...,都是递归嵌套的

node_modules
├─ express
│  ├─ index.js
│  ├─ package.json
│  └─ node_modules
│     ├─ accepts
│     │  ├─ index.js
│     │  ├─ package.json
│     │  └─ node_modules
│     │     ├─ mime-types
|     |     |   └─ node_modules
|     |     |      └─ mime-db
|     │     └─ negotiator
│     ├─ array-flatten
│ 		├─ ...
│  		└─ ...
└─ A
   ├─ index.js
   ├─ package.json
   └─ node_modules
      └─ accepts
         ├─ index.js
         ├─ package.json
         └─ node_modules
            ├─ mime-types
            |   └─ node_modules
            |      └─ mime-db
            └─ negotiator

规划缺点

这种嵌套依靠树的规划的确存在几个严峻的问题

  1. 途径过长问题: 因为包的嵌套结构 , node_modules 的目录结构可能会变得十分深,乃至可能会超出体系途径长度上限 ,究竟 windows 体系的文件途径默许最多支撑 256 个字符
  2. 磁盘空间糟蹋: 多个包之间不免会有公共的依靠,公共依靠会被屡次装置在不同的包目录下,导致磁盘空间被很多糟蹋 。比方上面 express 和 A 都依靠了 accepts,它就被装置了两次
  3. 装置速度慢:因为依靠包之间的嵌套结构,npm 在装置包时需求屡次处理和下载相同的包,导致装置速度变慢,尤其是在依靠联系杂乱的项目中

其时 npm 还没处理这些问题, 社区便推出了新的处理计划 ,便是 yarn。 它引入了一种新的依靠办理方法——扁平化依靠。

看到 yarn 的成功,npm 在 3.0 版别中也引入了相似的扁平化依靠结构

yarn

yarn 的首要改善之一便是经过扁平化依靠结构来处理嵌套依靠树的问题,具体来说

铺平,yarn 尽量将一切依靠包装置在项目的顶层 node_modules 目录下,而不是嵌套在各自的 node_modules 目录中。

这样一来,减少了目录的深度,避免了途径过长的问题 ,也尽可能避免了依靠被屡次重复装置的问题

咱们能够在 yarn-example 看到整个目录,悉数铺平在了顶层 node_modules 目录下,打开下面的包大部分是没有二层 node_modules

可是,有些依靠包仍是会在自己的目录下有一个 node_modules 文件夹,呈现嵌套的状况,例如 yarn-example 下的http-errors 依靠包就有自己的 node_modules,原因是:

当一个项目的多个依靠包需求同一个库的不同版别时,yarn 只能将一个版别的库提高到顶层 node_modules 目录中。 关于需求这个库其他版别的依靠,yarn 仍然需求在这些依靠包的目录下创立一个嵌套的 node_modules 来寄存不同版别的包

比方,包 A 依靠于 [email protected],而包 B 依靠于 [email protected]。因为这两个版别的 lodash 不能兼并,yarn 会将 [email protected] 提高到顶层 node_modules,而 [email protected] 则被嵌套在包 B 的 node_modules 目录下。

鬼魂依靠

尽管 yarn 和 npm 都采用了扁平化的计划来处理依靠嵌套的问题,但这种计划自身也有一些缺点,其间鬼魂依靠是一个首要问题。

鬼魂依靠,也便是你分明没有在 package.json 文件中声明的依靠项,但在项目代码里却能够 require 进来

这个也很简单了解,因为依靠的依靠被扁平化装置在顶层 node_modules 中,所以咱们能拜访到依靠的依靠

可是这样是有危险的,因为没有显式依靠,未来某个时分这些包可能会因为某些原因消失(例如新版别库不再引证这个包了,然后咱们更新了库),就会引发代码运转过错

糟蹋磁盘空间

而且还有一个问题,便是上面说到的依靠包有多个版别的时分,只会提高一个,那其他版别的包不仍是仿制了很屡次么,仍然有糟蹋磁盘空间的问题

那社区有没有处理这俩问题的思路呢? pnpm 便是其间最成功的一个

pnpm

pnpm 经过大局存储和符号链接机制从本源上处理了依靠重复装置和途径长度问题,一起也避免了扁平化依靠结构带来的鬼魂依靠问题

pnpm 的优势归纳来说便是“快、准、狠”:

  • 快:装置速度快
  • 准:装置过的依靠会精确复用缓存,乃至包版别晋级带来的改变都只 diff,绝不糟蹋一点空间
  • 狠:直接废掉了鬼魂依靠

履行 npm add express,咱们能够在 pnpm-example 看到整个目录,因为只装置了 express,那 node_modules 下就只有 express

那么一切的(次级)依靠去哪了呢? binggo,在node_modules/.pnpm/目录下,.pnpm/ 以平铺的方法储存着一切的包

三层寻址

  1. 一切 npm 包都装置在大局目录 ~/.pnpm-store/v3/files 下,同一版别的包仅存储一份内容,乃至不同版别的包也仅存储 diff 内容。
  2. 顶层 node_modules 下有 .pnpm 目录以打平结构办理每个版别包的源码内容,以硬链接方法指向 pnpm-store 中的文件地址。
  3. 每个项目 node_modules 下装置的包以软链接方法将内容指向 node_modules/.pnpm 中的包。

所以每个包的寻觅都要经过三层结构:node_modules/package-a > 软链接 node_modules/.pnpm/[email protected]/node_modules/package-a > 硬链接 ~/.pnpm-store/v3/files/00/xxxxxx

这便是 pnpm 的完成原理。官方给了一张原理图,能够调配食用

前面说过,npm 包都被装置在大局 pnpm store ,默许状况下,会创立多个存储(每个驱动器(盘符)一个),并在项目地点盘符的根目录

所以,同一个盘符下的不同项目,都能够共用同一个大局 pnpm store,绝绝子啊👏,大大节省了磁盘空间,提高了装置速度

软硬链接

也便是说,一切的依靠都是从大局 store 硬衔接到了 node_modules/.pnpm 下,然后之间经过软链接来相互依靠。

那么,这儿的软衔接、硬链接究竟是什么东西?

硬链接是指向磁盘上原始文件地点的同一方位 (直接指向相同的数据块)

软衔接能够了解为新建一个文件,它包括一个指向另一个文件或目录的途径 (指向方针途径)

.npmrc

shamefully-hoist,默许 false

  • false:node_modules下只能看到直接依靠的套件,次级依靠在node_modules/.pnpm 目录下;无法拜访其他子包部分装置的依靠项,例如,vue-dome2 装置的 lodash,vue-dome1 是拜访不到的
  • true:將一切套件都拉升到 node_modules 目錄下,能拜访到其他子包部分装置的依靠项,例如,vue-dome2 装置的 lodash,vue-dome1 是能拜访到的
// .npmrc

# pnpm 装备
shamefully-hoist=false

总结

npm2 的嵌套结构: 每个依靠项都会有自己的 node_modules 目录,导致了依靠被重复装置,严峻糟蹋了磁盘空间💣;在依靠层级比较深的项目中,乃至会超出 windows 体系的文件途径长度💣

npm3+ 和 Yarn 的扁平化战略: 尽量将一切依靠包装置在项目的顶层 node_modules 目录下,处理了 npm2 嵌套依靠的问题。可是该计划有一个严重缺点便是“鬼魂依靠”💣;而且依靠包有多个版别时,只会提高一个,那其他版别仍然会被重复装置,仍是有糟蹋磁盘空间的问题💣

pnpm大局存储和符号链接机制: 结合软硬链和三层寻址,处理了依靠被重复装置的问题,愈加反常的是,同一盘符下的不同项目都能够共用一个大局 pnpm store。节省了磁盘空间,而且底子不存在“鬼魂依靠”,装置速度还贼快💪💪💪

参阅文档

weekly/前沿技术/253.精读《pnpm》
pnpm 是凭什么对 npm 和 yarn 降维冲击的)
平铺的结构不是 node_modules 的仅有完成方法 | pnpm中文网

扫描二维码推送至手机访问。

版权声明:本文由51Blog发布,如需转载请注明出处。

本文链接:https://www.51blog.vip/?id=420

标签: 前端架构
分享给朋友:

“pnpm 是怎么推翻 npm 和 yarn 的?” 的相关文章

ThreeJs-03原料进阶

ThreeJs-03原料进阶

一.uv贴图 在3D核算机图形学中,UV映射是一种将2D纹路映射到3D模型外表的办法。在这儿,“U”和“V”代表了2D纹路空间的坐标,这与2D笛卡尔坐标体系中的“X”和“Y”是相似的。在3D模型的每个极点上,都会有一组对应的UV坐标,它们界说了3D模型在这个极点上的外表应当对应纹路图画的哪个部分。...

极致功能优化:前端SSR烘托利器Qwik.js

极致功能优化:前端SSR烘托利器Qwik.js

导言 前端功能已成为网站和运用成功的要害要素之一。用户希望快速加载的页面和流通的交互,而前端结构的挑选关于完结这些方针至关重要。但是,传统的前端结构在某些情况下或许面对功能应战且存在技能壁垒。 在这个充溢应战的布景下,咱们引入了 Qwik.js 结构。Qwik.js 不只是一个前端结构,更是一种前端...

react 知识点汇总(十分全面)

react 知识点汇总(十分全面)

React 是一个用于构建用户界面的 JavaScript 库,由 Facebook 开发并保护。它的核心理念是“组件化”,行将用户界面拆分为可重用的组件。 React 的组件一般运用 JSX(JavaScript XML)。JSX 是一种 JavaScript 语法扩展,答应开发者在 JavaSc...

css鼠标变小手, 什么是鼠标变小手样式?

css鼠标变小手, 什么是鼠标变小手样式?

要将CSS中的鼠标指针变为小手形状,你可以使用`cursor`属性并设置其值为`pointer`。这样,当用户将鼠标悬停在具有该样式的元素上时,鼠标指针就会变成一个小手形状,表示该元素是可点击的。下面是一个简单的示例:```cssa { cursor: pointer;}```这段代码会将所有``...

html5格式,html5官网首页

HTML5 是一种用于创建网页和网页应用的标记语言。它是 HTML 的第五个修订版本,旨在提高跨平台的兼容性、增强多媒体支持、提高性能和简化代码。HTML5 的主要特点包括:3. Canvas 和 SVG:HTML5 引入了 `` 元素,允许开发者通过 JavaScript 在网页上绘制图形。同时,...

html网页特效代码,html官方下载免费版

html网页特效代码,html官方下载免费版

创建一个HTML网页特效需要结合HTML、CSS和JavaScript。下面是一个简单的示例,创建一个带有旋转特效的按钮:```html旋转特效按钮 .rotatebutton { padding: 10px 20px; backgroundcolor: 4CAF50; colo...