pnpm包管理的高效存储机制解析

掘金
随着 pnpm 的逐渐崭露头角,越来越多的开发者和项目开始倾向于采用 pnpm 作为其包管理工具,以期利用 pnpm 的独特优势来解决 npm 在处理大型、复杂项目时可能遇到的一些问题。特别是在 Vue 3 及其生态中的许多包迁移使用pnpm做完包管理器后,这个趋势变得更为明显。pnpm 通过其独特的包管理策略和硬链接、软链接技术,以及三层寻址策略,显著减少了冗余数据,并提升了依赖解析的效率。同时,在 Node.js 环境中,理解如何处理依赖引用的逻辑是至关重要的。随着时间的推移,npm 也从简单的依赖解析演变为现今更为成熟和复杂的依赖管理系统。下面,我们将探讨 pnpm 的包管理策略、Node.js 在处理依赖引用时的逻辑、npm 的依赖历史、硬链接与软链接的原理,以及全局 pnpm-store 的组织方式。

一、pnpm的包管理策略带来的优点

  1. 磁盘空间效率:
    pnpm 使用一个公共内容地址able的存储区域来存放所有的包。每个版本的每个包在磁盘上只存储一次。如果多个项目使用相同的包和版本,pnpm 只需使用符号链接(或硬链接,取决于系统和配置)来链接到公共存储位置。这种方法节省了大量磁盘空间,而 npm 7 会在每个项目的 node_modules 文件夹中独立存储每个包的副本。
  2. 安装速度:
    由于 pnpm 使用符号链接,所以它的安装速度通常更快,尤其是在多个项目使用相同的依赖时。
  3. 更强的隔离性:
    pnpmnode_modules 结构确保了包只能访问其声明的依赖,这提供了更强的隔离性,能更早地捕获到未声明的依赖问题,而 npm 的扁平结构可能会隐藏这类问题,造成幻影依赖。

二、Node.js 在处理依赖引用时的逻辑

这里先简要描述下Node.js 在处理依赖引用时的逻辑,当使用 require()函数导入模块时,Node.js 的解析方式如下:

  1. 如果参数指向的是核心模块(如“fs”或“path”)或是一个绝对或相对的文件路径(例如./packageA.js/myLib/packageB.js),Node.js 将直接加载相应的文件或模块。

  2. 对于其他情况,Node.js 会启动对 node_modules目录的搜索流程:

    1. 首先,Node.js 会在当前的工作目录下查找node_modules
    2. 如果在当前目录未找到,它会逐级向上移动到父目录进行查找。
    3. 这一过程会持续进行,直到达到系统的根目录。
  3. 一旦找到node_modules目录,Node.js 会在目录中查找具有指定模块名的.js文件,或者一个与模块名同名的子目录。

三、 npm的依赖历史

从npm的诞生开始,其嵌套的node_modules目录结构旨在解决版本冲突,确保每个项目都有特定版本的依赖。但这也导致了大量的磁盘空间浪费。在 npm1、npm2 中呈现出的是嵌套结构,类似下面这样:
(packageA 依赖 packageB 依赖 packageN…)

```
node_modules
    └─ packageA
    ├─ index.js
    ├─ package.json
    └─ node_modules
        └─ packageB
        ├─ index.js
        └─ package.json
        └─ node_modules
            └─ ... 
```

是以依赖包之间互相嵌套的方式存储的,这样最明显的一个问题就是依赖的层级有可能很深,包A 依赖 包B 依赖 包C…,这会造成文件路径长度过长的问题,另外还会磁盘空间的浪费:相同的包可能被多次安装在不同的嵌套级别上,导致了不必要的重复和空间的浪费。结合上面说的node.js的解析依赖的方式在层级过深的时候要进行大量文件的 I/O 操作,效率不高。

当npm进入其第三个主要版本(npm@3)时,它引入了一个显著的变化,即扁平化的依赖管理。包括 yarn,都着手来通过扁平化依赖的方式来避免前两个版本中常见的嵌套node_modules结构。

image.png
上面图片里只安装了一个 axios 作为项目的依赖,但是node_modules里却多出了很多其他的包。这就是扁平化依赖管理的结果。相比之前的嵌套结构,现在的目录结构类似下面这样:


                
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值