npm, yarn, pnpm之间的区别

在这里插入图片描述

前言

在现代化的开发中,一个人可能同时开发多个项目,安装的项目越来越多,所随之安装的依赖包也越来越臃肿,而且有时候所安装的速度也很慢,甚至会安装失败。

因此我们就需要去了解一下,我们的包管理器,在前端比较主流的包管理器主要有三个(当然还有其他优秀的包管理器,本文主要介绍这三个),分别是:npm,yarn,pnpm

幽灵嵌套(Phantom Dependency)

在了解包管理器之前,我们先了解一下包管理的一个难题:幽灵嵌套

幽灵嵌套问题通常发生在依赖之间存在复杂的版本要求时,比如:

  • 包 A 依赖于包 B@1.0.0
  • 包 B 依赖于包 C@2.0.0
  • 另一个包 D 也依赖于 C@3.0.0

在传统的依赖管理中,可能会导致包 C 的不同版本被嵌套在不同的子依赖树中,从而在 node_modules 中形成不同路径的多层嵌套,导致路径非常深。这种情况一旦发生,如果包 A 和包 D 不同意版本要求,可能会导致不同版本的包 C 被分别安装在不同的路径下,出现路径冲突甚至依赖问题,这就是“幽灵嵌套”现象。

NPM (Node Package Manager)

概述:

npm 是 Node.js 默认的包管理工具,最早由 Node 社区开发并捆绑到 Node.js 中,因此使用最为广泛。

从npm v2 到npm v7+的升级过程中,从最初使用递归的方法处理依赖,造成高度嵌套的依赖树,到后来使用扁平化管理,一定程度上解决了依赖嵌套问题,但是出现了算法时间过长的问题,最后引入了package-lock.json机制,作用是锁定依赖结构,一定程度上保持了依赖的稳定性

核心:

  • 采用扁平化依赖管理管理方式
  • 每个依赖包都会在 node_modules 中单独安装
  • 相同的依赖可能会被重复安装多次

特点:

  • 优点:
  1. Node.js 默认包管理器,使用最广泛,拥有强大的额社区支持
  2. 最早的包管理器,简单易上手,对初学者友好
  3. package-lock.json 保证依赖版本一致性
  • 缺点:
  1. 安装速度较慢,占用空间大

目录结构:

  • npm v2及以前
  1. 依赖树可能非常深
  2. 相同包会重复安装
  3. 占用大量磁盘空间
  4. 文件路径可能超过 Windows 限制
node_modules
├── A
│   └── node_modules
│       └── B
│           └── node_modules
│               └── C
└── D
    └── node_modules
        └── B
            └── node_modules
                └── C
  • npm v3-6,扁平化管理
  1. 采用扁平化优先的安装策略
  2. 相同版本的包会被提升到顶层
  3. 不同版本保留在各自的 node_modules 中
  4. 安装算法比较复杂,需要计算依赖树
// 假设依赖关系:
// package-A 依赖 lodash@4.0.0
// package-B 依赖 lodash@4.0.0

node_modules
├── package-A
├── package-B
└── lodash     // 被提升到顶层

当有版本冲突时:

// package-A 依赖 lodash@4.0.0
// package-B 依赖 lodash@3.0.0

node_modules
├── package-A
├── package-B
│   └── node_modules
│       └── lodash  // 3.0.0 版本
└── lodash         // 4.0.0 版本提升到顶层
  • npm v7+, 改进了扁平化管理,引入peer dependencies 处理
  1. 自动安装 peer dependencies
  2. 更严格的版本锁定
  3. 改进了依赖解析算法
  4. workspaces 支持
node_modules
├── package-A
├── package-B
├── lodash        // 主版本
└── .package-lock.json  // 更严格的版本锁定

Yarn

概述:

Yarn 是一个 JavaScript 包管理工具,最早由 Facebook 推出,主要用于管理项目中的依赖包。和 npm 类似,yarn 解决了在 JavaScript 项目中下载、安装和管理依赖的需求,并在一定程度上改进了 npm 的一些缺点,比如性能、稳定性和安全性。

核心:

  1. 并行下载提升安装速度:

传统的 npm 安装方式是依次下载依赖,而 Yarn 可以同时下载多个依赖,称为“并行下载”。这种方式充分利用了网络带宽,显著减少安装依赖所需的时间,使得安装速度更快。并行下载尤其在大型项目中效果显著,能够有效降低整体安装时间。

  1. 缓存机制减少重复下载:

Yarn 内置了缓存机制,在首次安装依赖时会将其缓存到本地。之后再次安装这些依赖时,如果依赖版本没有改变,Yarn 会直接从本地缓存中读取,而不是重新下载。这样不仅节省了网络请求,还提升了安装速度,特别适合离线开发和持续集成场景。

  1. yarn.lock 确保依赖版本一致性:

Yarn 使用 yarn.lock 文件记录每个依赖的具体版本和来源,确保团队所有成员在不同机器上安装时得到的依赖版本完全一致。这避免了“依赖地狱”问题,即由于版本不一致导致的错误或不兼容情况,从而提高了开发过程的稳定性。

  1. 更安全的依赖解析机制:

Yarn 在安装依赖时会校验每个包的完整性(如 SHA 校验),以确保包的内容没有被篡改。这种安全机制能在下载依赖时检测到潜在的包篡改或恶意代码的引入,增强了项目的安全性。相比于早期的 npm,Yarn 的这种依赖解析机制更加严谨。

  1. Workspace 支持更好的 monorepo 管理:

Yarn 支持 Workspace 功能,允许在单个代码库(monorepo)中管理多个项目或包。这种管理方式可以将多个子项目的依赖集中管理、共享,减少重复依赖的安装。此外,Yarn 还能通过 Workspace 在多个包之间建立相互依赖关系,使 monorepo 项目的开发、构建和测试更加高效。

  1. PnP(Plug’n’Play)模式提供更快的模块加载:

Yarn 2.x 引入了 PnP 模式,这种模式完全去除了 node_modules 目录,通过在 .pnp.cjs 文件中记录依赖映射关系。PnP 不仅减少了磁盘空间的占用,还提升了依赖的加载速度,因为 Node.js 不再需要递归遍历 node_modules。这样可以加快应用的启动速度,同时在依赖数量庞大的项目中减少文件系统的压力。

特点:

  • 优点:
  1. 采用扁平化优先 + 符号链接(符号链接是一个特殊的文件,它包含对另一个文件或目录的引用路径)的组合策略
  2. 相同版本的包会被提升并复用
  3. 不同版本通过符号链接保持正确的引用关系
  • 缺点:
  1. 仍然存在幽灵依赖问题
    尽管 Yarn 已经在扁平化和依赖管理上做了优化,但在一些复杂的项目中仍然会出现幽灵依赖问题。所谓幽灵依赖,指的是某个包在项目中使用但并未在 package.json 中声明,可能是通过其他依赖的间接依赖引入。这种隐式依赖会导致项目依赖关系难以维护,如果间接依赖被移除,可能会导致项目出错。

  2. 某些场景下的依赖解析较慢
    Yarn 的依赖解析虽然比传统 npm 更快,但在依赖结构复杂、依赖版本冲突较多的情况下,解析和处理依赖关系可能会变慢。尤其在 monorepo 中,Yarn 需要处理多个包之间的依赖关系,可能出现解析速度不如 pnpm 的情况。

目录结构:

  • 基本结构
node_modules/
├── package-A/                # 实际文件
├── package-B/                # 实际文件
├── lodash/                   # 提升到顶层的共享包
└── .bin/                     # 可执行文件的符号链接
  • 依赖共享案例
// 假设有以下依赖关系:
项目
├── package-A (依赖 lodash@4.0.0)
└── package-B (依赖 lodash@4.0.0)

// Yarn 会创建这样的结构:
node_modules/
├── package-A/
│   └── node_modules/
│       └── lodash -> ../../../lodash  # 符号链接
├── package-B/
│   └── node_modules/
│       └── lodash -> ../../../lodash  # 符号链接
└── lodash/                            # 实际文件
  • 版本冲突处理
// 当存在版本冲突时:
项目
├── package-A (依赖 lodash@4.0.0)
└── package-B (依赖 lodash@3.0.0)

// Yarn 会这样处理:
node_modules/
├── package-A/
│   └── node_modules/
│       └── lodash -> ../../../lodash    # 指向4.0.0
├── package-B/
│   └── node_modules/
│       └── lodash/                      # 本地安装3.0.0
└── lodash/                              # 4.0.0版本在顶层

PNPM(Performant NPM)

概述:

pnpm 是一个更现代化的包管理工具,旨在解决 npm 和 yarn 的一些效率和资源管理问题。

  • 核心:
  1. 采用内容寻址存储系统:

pnpm 使用内容寻址(content-addressable storage)来存储依赖包。每个依赖包都会被哈希处理,并根据其内容生成唯一的存储地址。这样,即使多个项目依赖于相同版本的包,pnpm 也只需要存储一份,不会重复存储同样内容的文件。

  1. 使用硬链接和符号链接共享依赖:

pnpm 通过在 node_modules 中创建硬链接或符号链接(symlink),指向内容寻址存储中实际的依赖包。这样每个项目可以“共享”依赖,而不必为每个项目单独存储依赖包内容。

  • 硬链接(Hard Link) :将文件内容链接到项目文件夹下,不占用额外磁盘空间。
  • 符号链接(Symlink) :为特定版本的包创建路径映射,使项目代码能够准确找到每个依赖包版本的地址。

特点:

  • 优点:
  1. 显著节省磁盘空间
  2. 安装速度快
  3. 更严格的依赖管理
  4. pnpm-lock.yaml 确保依赖版本一致
  • 缺点:
  1. 不兼容一些使用传统 node_modules 结构的工具和插件:

  2. 在 pnpm 中,每个依赖都有自己的隔离路径,某些工具、插件或构建系统可能会假设 node_modules 目录是扁平的,这可能导致兼容性问题。

  3. 与本地开发和测试环境的潜在不兼容:

  4. 有些项目依赖于本地 node_modules 结构,或者需要直接访问 node_modules 中的文件。在 pnpm 使用内容寻址和符号链接时,这可能会导致某些工具无法正常运行。

目录结构

  • 内容寻址存储
.pnpm-store/
└── v3/
    └── files/
        ├── 00/                              # 前两位哈希值作为目录名
        │   └── deadbeef...                  # 包内容的哈希值
        └── ff/
            └── cafebabe...                  # 另一个包的哈希值
  • 依赖结构
node_modules/
├── .pnpm/
│   ├── react@17.0.2/
│   │   └── node_modules/
│   │       ├── react/                       # 实际文件(硬链接到 store)
│   │       └── loose-envify/                # react 的依赖
│   └── lodash@4.17.21/
│       └── node_modules/
│           └── lodash/                      # 实际文件(硬链接到 store)
├── react -> .pnpm/react@17.0.2/node_modules/react                 # 符号链接
└── lodash -> .pnpm/lodash@4.17.21/node_modules/lodash             # 符号链接

目录说明

  • .pnpm/ 文件夹:存放项目的所有依赖包,按 包名@版本号 命名,并在其 node_modules 文件夹中包含该包的实际文件和依赖项。

  • 硬链接:.pnpm 中的实际文件并不是直接复制到每个项目中,而是通过硬链接指向 pnpm 的全局缓存存储目录 (pnpm store)。这样,不同项目间的相同版本依赖不需要重复下载。

  • 符号链接:pnpm 会在项目的 node_modules 根目录创建符号链接,将每个包链接到 .pnpm 中实际的包路径。例如:

  • node_modules/react 是一个符号链接,指向 .pnpm/react@17.0.2/node_modules/react
    node_modules/lodash 符号链接指向 .pnpm/lodash@4.17.21/node_modules/lodash

工作原理

  • 包安装:pnpm 会将依赖包下载到全局缓存 (pnpm store) 中,并将实际文件硬链接到 .pnpm 文件夹中的特定版本目录下。
  • 创建符号链接:在项目的 node_modules 文件夹内创建符号链接,将包名称指向 .pnpm 中的对应路径。
  • 引用:项目中的 require(‘react’) 会自动找到 node_modules/react 符号链接,并通过符号链接访问实际文件。

总结:

三者同异:

在这里插入图片描述

使用选择:

基于这些特点:

  • 如果项目体积较小,团队成员 Node.js 经验不同,推荐使用 npm
  • 如果需要更好的性能和可靠性,推荐使用 yarn
  • 如果需要最严格的依赖管理、最小的磁盘空间占用,推荐使用 pnpm

常用命令:

npm、yarn 和 pnpm 的常用命令对比表:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/930375.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用Java将PDF文件解析成Excel文件

安装pom依赖 <!-- 解析pdf--><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.27</version> <!-- 请检查并使用最新版本 --></dependency>测试读取pdf文件…

Celery使用小结

介绍 Celery 是异步任务调度工具就&#xff0c;或分布式任务队列&#xff08;Distributed Task Queue&#xff09;&#xff0c;有多个worker。 Broker&#xff1a;中间人&#xff0c;所有任务放在broker中&#xff0c;worker到broker中提取任务执行。 这样系统为开环系统&am…

java注解(二):注解的解析以及应用场景、用注解和反射模拟junit框架代码演示

目录 1、什么是注解的解析&#xff1f; 2、解析注解的案例 1、自定义一个注解 2、在类和方法上使用自己定义的注解 3、解析注解 3、模拟Junit框架案例 1、自定义一个MyTest注解 2、定义一个测试类&#xff0c;使用自定义的注解 3、写一个启动类 本文章主要讲解什么是注…

VUE脚手架练习

脚手架安装的问题&#xff1a; 1.安装node.js,配置环境变量,cmd输入node -v和npm -v可以看到版本号&#xff08;如果显示不是命令&#xff0c;确认环境变量是否配置成功&#xff0c;记得配置环境变量之后重新打开cmd&#xff0c;再去验证&#xff09; 2.在安装cnmp时&#xf…

unity3d—demo(实现给出图集名字和图片名字生成对应的图片)

目录 实现给出图集名字和图片名字生成对应的图片&#xff1a; 代码示例&#xff1a; dic: 键 是图集名称 值是一个字典 该字典键是图片名称 值是图片&#xff0c;结构如图&#xff1a; 测试代码&#xff1a; 结果&#xff1a; SpriteRenderer 讲解&#xff1a; Resour…

国内外网络安全政策动态(2024年11月)

▶︎ 1.13项网络安全国家标准自11月1日起实施 11月1日起&#xff0c;《网络安全技术 信息技术安全评估准则》等13项网络安全国家标准开始实施&#xff0c;其中&#xff0c;《网络安全技术 信息技术安全评估准则 第1-5部分》《网络安全技术 信息技术安全评估方法》等6项推荐性国…

Modbus Poll的使用

最近从串口调试助手接触到了Modbus Poll&#xff0c;一开始用的时候有些生疏&#xff0c;了解之后不得不说真香。 相对于串口调试助手&#xff0c;有些设备厂家会给一些点表和指令码&#xff0c;有些也可以通过modbus协议解析出来&#xff0c;相对来说&#xff0c;使用Modbus …

写NFC标签支持Android安卓Ohos纯血鸿蒙唤醒微信小程序

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?spma21dvs.23580594.0.0.52de2c1b8bEEGz&ftt&id61539185785 Python languagecodestr "en".encode(gbk) titlestrself.lineEdit_title.text().strip().encode(gbk) uriheaderindex sel…

利用oracle spool配置数据导出脚本

一&#xff0c;spool配置项 set colsep |   //域输出分隔符 set echo off   //显示start启动的脚本中的每个sql命令&#xff0c;缺省为on set feedback off //回显本次sql命令处理的记录条数&#xff0c;缺省为on set heading off  //输出域标题&#xff0c;缺省为on…

单端和差分信号的接线法

内容来源&#xff1a;【单端信号 差分信号与数据采集卡的【RSE】【 NRES】【 DIFF】 模式的连接】 此篇文章仅作笔记分享。 单端输入 单端信号指的是输入信号由一个参考端和一个信号端构成&#xff0c;参考端一般是地端&#xff0c;信号就是通过计算信号端口和地端的差值所得…

前端基础——CSS

美化文档 HTML内部添加样式 本节我们来学习如何在标签中引入CSS样式。 1 在标签中添加声明 声明的关键字是style后接等号&#xff08;&#xff09;再接引号&#xff08;""&#xff09;&#xff0c;即style"" 具体声明如下&#xff1a; <input typ…

MATLAB 最小二乘点云拟合球 (89)

MATLAB 最小二乘点云拟合球 (89) 一、算法介绍二、算法实现1.代码2.结果这是缘,亦是最美的相见 一、算法介绍 球面拟合算法是一种通过数学方法将一组三维点(通常在三维空间中分布)拟合到一个理想的球形表面上。这个过程通常涉及使用最小二乘法来最小化实际数据点与拟合的…

安防视频监控平台Liveweb视频汇聚管理系统管理方案

智慧安防监控Liveweb视频管理平台能在复杂的网络环境中&#xff0c;将前端设备统一集中接入与汇聚管理。国标GB28181协议视频监控/视频汇聚Liveweb平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、…

elasticsearch-如何给文档新增/更新的字段

文章目录 前言elasticsearch-如何给文档新增/更新的字段1. 如何给某些文档新增/更新的字段2. 给所有文档添加/更新一个新的字段3. 测试 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且…

浅谈网络 | 应用层之流媒体与P2P协议

目录 流媒体名词系列视频的本质视频压缩编码过程如何在直播中看到帅哥美女&#xff1f;RTMP 协议 P2PP2P 文件下载种子文件 (.torrent)去中心化网络&#xff08;DHT&#xff09;哈希值与 DHT 网络DHT 网络是如何查找 流媒体 直播系统组成与协议 近几年直播比较火&#xff0c;…

性能测试基础知识jmeter使用

博客主页&#xff1a;花果山~程序猿-CSDN博客 文章分栏&#xff1a;测试_花果山~程序猿的博客-CSDN博客 关注我一起学习&#xff0c;一起进步&#xff0c;一起探索编程的无限可能吧&#xff01;让我们一起努力&#xff0c;一起成长&#xff01; 目录 性能指标 1. 并发数 (Con…

【机器学习】机器学习的基本分类-监督学习-决策树-ID3 算法

ID3&#xff08;Iterative Dichotomiser 3&#xff09;是决策树的一种构造算法&#xff0c;由 Ross Quinlan 在 1986 年提出。它主要用于分类问题&#xff0c;通过信息增益选择特征来构建决策树。ID3 假设数据是离散型特征&#xff0c;且不支持连续型数据。 1. 核心思想 划分标…

记录:ubuntu 使用chattts的过程。

你知道什么是穷人吗&#xff1f;穷人就是没钱还想学习。 git GitHub - 2noise/ChatTTS: A generative speech model for daily dialogue. 因为所以。cosyvoice&#xff0c;gpt-s . 0.先找一个目录吧。 1.命令行模式 duyichengduyicheng-computer:~/gitee$ git clone https:…

LabVIEW氢同位素单质气体定量分装系统

氢同位素单质气体在多个行业中有重要应用&#xff0c;如能源和化工。传统的分装方法面临精度和自动化程度不足的问题。为此&#xff0c;开发了一套基于LabVIEW和质量流量控制器的定量分装系统&#xff0c;提高分装精度和效率&#xff0c;同时减少资源浪费和环境污染。 项目背景…

分类预测 | PSO-PNN粒子群优化概率神经网络多特征分类预测

分类预测 | PSO-PNN粒子群优化概率神经网络多特征分类预测 目录 分类预测 | PSO-PNN粒子群优化概率神经网络多特征分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现PSO-PNN粒子群优化概率神经网络多特征分类预测&#xff0c;运行环境Matlab2018b及以…