为什么 pnpm 安装速度快,节省磁盘空间?

pnpm主打的就是一个速度快,节省磁盘空间,本文就来看一下,pnpm为什么能够速度快,节省磁盘空间

背景

前端早期没有包管理的时候,

  • 开发人员需要手动下载、管理和更新项目所需的所有依赖项。这需要花费大量的时间和精力,容易出错,并且难以跟踪和维护;
  • 并且版本控制困难,很难确保项目的依赖项使用正确的版本,开发人员可能会遇到依赖项版本冲突和兼容性问题,因为手动管理依赖项时很难追踪和控制所使用的特定版本。
  • 每个开发者都需要手动下载和配置项目的依赖项,导致了重复劳动和可能的错误,特别是在团队合作的项目中。
  • 包管理器提供了丰富的开源库和工具生态系统,开发人员可以轻松地从中选择适合自己项目需求的依赖项,如果不使用包管理器,就无法充分利用这个生态系统,而需要自己编写和维护大量的代码
html 复制代码
<!DOCTYPE html>
<html>
<body>
  <!-- 如果没有包管理器 -->
  <!-- 开发人员需要手动下载并将外部库的脚本文件d的正确版本通过script引入 -->
  <script src="xxx"></script>
  <script src="yyy"></script>
  // ...
</body>
</html>

于是npm和yarn相继推出,但是npm和yarn有一些明显缺陷

  • 1、npm3以下,node_modules是嵌套结构,多个包之间可能有相同版本的公共依赖,一层层嵌套复制,没有复用,重复安装,浪费磁盘空间,而且嵌套越深,路径越长,可能会超过windows的最长路径限制。 安装个axios,项目node_modules结构就是这样:
txt 复制代码
    axios
    |- node_modules
       |-- follow-redirects
       |-- form-data
       |   |- node_modules
       |      |-- asynckit
       |      |-- combined-stream
       |      |   |- node_modules
       |      |       |-- delayed-stream
       |      |-- mime-types
       |          |- node_modules
       |             |-- mime-db
       |-- proxy-from-env
        
  • 2、 npm3+和yarn,node_modules是扁平结构,比如项目只安装个axios,

axios的依赖也被提到最外层的node_modules中,axios的依赖form-data的依赖asynckit也被安装到最外层的node_modules中,这样好处是,相同依赖且版本相同就不会重复安装,一定程度上可以解决路径过长问题。

但是如果版本不同,还是会有嵌套,根据目录结构结算,只会把其中一个版本提升到最外层的node_modules中。

而且可以在项目里面,引入form-data这个包,尽管我并没有安装,在package.json的dependecies中没有显示声明,但是它在最外层的node_modules中,所以可以引入它,这是一个幽灵依赖问题,要是项目中把axios包删除了,那form-data这个包也被删除,项目就报错了。

所以pnpm应运而生,相对于npm,yarn具有碾压优势,在了解pnpm之前,先了解一下硬链接和软链接。

硬链接、软链接

硬链接(hard link) 就像是一个文件的复制品,但实际上它们共享同一个身份。可以将硬链接看作是一个人的复制品,无论你使用原始文件还是硬链接,它们都代表同一个文件。所以,如果你改变原始文件的名字或属性,硬链接也会相应地改变。

软链接 ,也叫符号链接,就像是一个符号或指示牌,它指向另一个文件的位置。可以将软链接看作是一个指向文件的指示牌,可以根据指示牌找到真正的文件。当你访问软链接时,系统会根据指示牌上的路径找到目标文件。桌面快捷方式就是软链接

  • 硬链接是文件的复制品,它们共享同一个身份,对其中一个的更改会影响其他链接。
  • 软链接是一个指向目标文件的符号,它只是一个文件的引用,对软链接的更改不会影响目标文件。

1、复制文件

磁盘中会再次复制一份,不会互相影响,平时最多的是右键复制,或者ctrl+c,也可以用命令复制,Windows命令 :copy a.js a.copy.js,Mac命令:cp a.js a.copy.js

2、文件硬链接

Windows命令:mklink /H b.hard.js b.js ,Mac命令:ln b.js b.hard.js

3、文件软链接

Window命令:mklink c.soft.js c.js,Mac命令:ln -s c.js c.soft.js,windows建立软连接需要管理员权限

pnpm的优势

同样,还是只安装一个axios,

不能访问没有声明的依赖

项目最外层node_modules里面只有一个.pnpmaxios两个文件,没有把所有依赖包铺平,在项目里面就不能引入其他包了,不存在幽灵依赖问题了

解决嵌套过深,路径过长

所有同版本的依赖包在硬盘仓库地址里面只保存一份,所有依赖包.pnpm里面铺平了,都是从磁盘的仓库地址硬链接过来的,这个axios还是一个软链接,指向/.pnpm/axios@1.6.2/node_moduoles/axios,axios所依赖的三个包在axios@1.6.2/node_moduoles中都是软链接,所有依赖包真正的位置 都在/.pnpm/packageName@version/node_modules/packageName,也没有嵌套层级过深,路径过长的问题了

节省磁盘空间

axios包、axios的依赖包、依赖包的依赖包,依赖包的依赖包的依赖包,...,都只在硬盘中只存在一份,其余的都是软链接,并且可以跨项目使用同一版本的依赖,比如有3个项目都用了axios@1.6.2这个版本,它在硬盘仓库地址只有一份,然后硬链接到这个3个项目的node_modules的.pnpm里面,这样空间就大大的节省了

安装速度快

使用 npm 时,依赖每次被不同的项目使用,整个包都会重复安装一次。

而使用pnpm时,假如你上一个项目已经使用pnpm安装了axios@1.6.1这个版本到硬盘仓库地址里面,新项目中,你要安装axios@1.6.2,假如这个两个版本中只有axios.js这个文件变动了,那么磁盘中只会重新安装这一个变动文件,然后硬链接到你新项目的.pnpm中,而不会因为仅仅一个文件的改变复制整新版本包的内容。这样既节省空间而且速度也更快。

pnpm 分三个阶段执行安装:

  1. 依赖解析,pnpm 具有并行安装的能力,可以同时解析获取多个包, 仓库中没有的依赖都被识别并获取到仓库,
  2. 根据依赖计算出node_modules 目录结构。
  3. 链接依赖项。 所有以前安装过的依赖项都会直接从仓库中获取并链接到 node_modules的.pnpm

这种方法比传统的三阶段安装过程(解析、获取和将所有依赖项写入node_modules)快得多。

参考:

www.pnpm.cn/

相关推荐
再吃一根胡萝卜1 小时前
08 · 前端:Vue3 + SSE 流式与执行链路可视化
面试
再吃一根胡萝卜1 小时前
03 · 后端:FastAPI 与分层架构
面试
mldong3 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排4 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60614 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角5 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!5 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰6 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
Interview Aid1126 小时前
Walmart Global Tech SDE 三轮面经|基础、并发、压力面
面试·职场和发展
mayaairi7 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js