[PNPM] 其他包管理器

news/2025/3/26 20:52:08/文章来源:https://www.cnblogs.com/Answer1215/p/18790508

Yarn

Yarn 这个包管理器是在 2016 的时候由 Facebook、Google、Exponent 以及 Tilde 团队共同开发推出的。

image-20240822104204072

当时 Yarn 的出现主要是为了解决 npm 在速度安全性以及一致性方面的一些问题:

  • 安装速度

  • 确定性:

    • 项目A ---> 直接依赖: libraryX(1.0)-----> 间接依赖:libraryY(1.3)
    • 项目A ---> 直接依赖: libraryX(1.0)-----> 间接依赖:libraryY(2.0)
    • Yarn 引入了一个 yarn.lock 锁文件
  • 安全性

  • 离线安装

指令对比:

npm Yarn 说明
npm init yarn init 初始化项目
npm install/link yarn install/link 默认的安装依赖操作
npm install <package> yarn add <package> 安装某个依赖
npm uninstall <pacakge> yarn remove <package> 移除某个依赖
npm install <package> --save-dev yarn add <pacakge> --dev 安装开发依赖
npm update <package> --save yarn upgrade <package> 更新某个依赖
npm install <package> --global yarn global add <pacakge> 全局安装
npm publish/login/logout yarn publish/login/logout 发布/登录/登出
npm run <script> yarn run <script> 执行 script 命令

Yarn 的出现让 npm 团队也感受到了压力,做出了一定的改变。

例如从 npm v5 开始引入了名为 package-lock.json 的锁文件,类似于 Yarn 的 yarn.lock 文件。这确保了在不同环境中的依赖结构一致性。

思考🤔:package.json 和 package-lock.json 都是 npm 用于管理项目依赖的文件,两者有什么不同呢?

答案:package.json包描述文件,会包含直接依赖以及元数据信息,package-lock.json 包含所有的依赖信息(包含直接依赖和间接依赖)。

pnpm

在 Yarn 之后,又出现了 pnpm包管理器

pnpm 的优势主要表现在这么 3 个地方:

  1. 节省磁盘空间
  2. 解决幽灵依赖
  3. 原生支持Monorepo

1. 节省磁盘空间

使用 npm 时,如果你有 100 个项目都使用同一个依赖项,你会在磁盘上保存该依赖项的 100 份副本。而使用 pnpm,依赖项会存储在一个内容可寻址的存储中。

16852383061314

pnpm中有两个比较重要的概念:

  • 硬链接
  • 符号链接

硬链接

是指多个文件名指向同一个物理文件数据块。这意味着,无论你通过哪个硬链接访问文件,看到的内容都是相同的。删除一个硬链接不会影响其他硬链接,只有当所有硬链接都被删除后,文件数据才会真正从硬盘中移除

image-20240828083651411

符号链接

符号链接是一个特殊的文件,包含了指向另一个文件或目录的路径。它类似于快捷方式,访问符号链接时,操作系统会将其重定向到实际文件或目录。符号链接本身占用少量空间,但它指向的文件或目录仍然占据实际存储空间。

image-20240828083944364

在 pnpm 中,直接依赖使用硬链接,而间接依赖使用符号链接。下面来做一个和 npm 安装包的对比:

两个项目 ProjectA 和 ProjectB,它们都依赖同一个库 libraryX。

传统的 npm 安装方式

ProjectA 和 ProjectB 都会在各自的 node_modules 文件夹中创建一个独立的 libraryX 目录,并且这些目录里包含了相同的文件内容。即使 libraryX 的版本完全相同,它们仍然会各自占用磁盘空间。

# 安装依赖
cd ProjectA
npm install libraryXcd ../ProjectB
npm install libraryX# 结果:
# ProjectA/node_modules/libraryX/ -> 这是一个完整的libraryX文件
# ProjectB/node_modules/libraryX/ -> 这是另一个完整的libraryX文件

这样,libraryX 的文件在磁盘上被重复存储了两次,即使它们的内容完全一样。

pnpm 使用硬链接的方式

当你使用 pnpm 安装 libraryX 时,pnpm 会将 libraryX 的文件存储在一个全局的内容地址存储(例如 ~/.pnpm-store)中,而不是在每个项目中都完整复制一份。

然后,pnpm 会为 ProjectA 和 ProjectB 中的 libraryX 创建硬链接。硬链接指向全局存储中的同一个物理文件,因此即使在 ProjectA 和 ProjectB 中都有 libraryX 的文件,这些文件在磁盘上只存储了一次。

# 使用 pnpm 安装依赖
cd ProjectA
pnpm install libraryXcd ../ProjectB
pnpm install libraryX# 结果:
# ~/.pnpm-store/libraryX/ -> 这是libraryX的实际物理文件,存储在全局内容地址存储中
# ProjectA/node_modules/libraryX/ -> 这是指向全局存储的硬链接
# ProjectB/node_modules/libraryX/ -> 这是另一个指向全局存储的硬链接

符号链接的使用

pnpm 在处理间接依赖时,会使用符号链接。

例如,假设 libraryX 本身依赖 libraryY,而 libraryY 也存储在全局内容地址存储中。此时 pnpm 会在 libraryX 中创建一个符号链接,指向全局存储中的 libraryY,而不是将 libraryY 的文件直接复制到 libraryX 中。这进一步减少了文件的重复存储。

# 符号链接示例:
# ProjectA/node_modules/libraryX/node_modules/libraryY -> 这是一个符号链接,指向全局存储中的libraryY

思考🤔:如果不同的项目依赖同一个包(libraryX)的不同版本,应该怎么处理?

答案:在全局仓库下分别存储每个版本的 libraryX. 但是这里有一个优化,仅存储不同版本之间不同的文件。

实战演练

使用 pnpm create vue@latest 命令分别创建两个 Vue 项目,查看依赖结构。

pnpm store path

2. 解决幽灵依赖

所谓幽灵依赖,是指当一个包(A)依赖于另一个包(B)时,后者会被放置在前者的 node_modules 目录中。这意味着一个包可能会意外地访问并使用另一个包的依赖,即使它没有在自己的 package.json 文件中声明这些依赖。

实战演练

演示 npm 和 pnpm 对于幽灵依赖的处理。

幽灵依赖会存在的问题:

  1. 难以理解的依赖关系
  2. 潜在的错误

3. 原生支持Monorepo

目前企业中搭建 Monorepo 项目方案,常见有这么几种:

  1. Lerna
  2. Yarn + Workspace
  3. pnpm + Workspace

4. 相关指令

  • 安装 pnpm:可以使用 npm 或者 yarn 进行安装,npm install -g pnpm
  • 创建新项目:pnpm init
  • 添加依赖:pnpm add <package>
  • 添加所有依赖:pnpm install
  • 升级依赖:pnpm update <package>
  • 删除依赖:pnpm remove <package>

包的隔离和提升

这是一张来自于 pnpm 官方给出的和其他包管理器之间的 对比图,如下:

image-20240821101002639

pnpm 默认策略是包隔离,老牌的 npm 的默认策略是包提升

  • 包隔离:是指在项目中,每个依赖包都有自己独立的安装环境,这样可以避免不同依赖之间的冲突。这个概念尤其重要,当不同的依赖包需要相同的子依赖但不同版本时,如果没有良好的隔离机制,就可能导致依赖版本冲突,进而导致项目运行错误或行为异常。
  • 包提升:是指将依赖关系中某些包提升到更高的目录层次,以减少冗余,节省磁盘空间

示例:假设我们有一个项目 MyApp,该项目依赖两个包 PackageA 和 PackageB(这两个包是直接依赖),这两个包又有相同的间接依赖:

  • PackageA 依赖 lodash@4.17.21
  • PackageB 依赖 lodash@3.10.1

在没有包隔离的情况下,传统的包管理工具(例如 npm 早期版本)可能会尝试将 lodash 的一个版本提升到项目的 node_modules 根目录。如果 lodash@4.17.21 被安装在根目录下,那么 PackageB 依赖的 lodash@3.10.1 就会被忽略,导致 PackageB 无法正常运行。

而 pnpm 默认采用的就是包隔离策略,自然不存在上面的问题。

思考🤔:包提升本质上是为了节省磁盘空间,pnpm 采用包隔离的话磁盘空间会有浪费么?

答案:不会,因为pnpm有全局的存储空间,最终不同版本的依赖都是存储在全局空间里面,本地项目通过硬链接连接到对应版本的包。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kioptrix Level_1

Kioptrix Level 1.1 靶场配置 导入靶场时先将vmx后缀文件中的带有ethernet0的配置行全部删除,再导入靶场,添加一个网络适配器即可 信息收集 查找目标主机ip ┌──(root㉿kali)-[~] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:84:b2:cc, IPv4: 192.168…

20244209韩仕炜《Python程序设计》实验一报告

课程:《Python程序设计》 班级: 2442 姓名:韩仕炜 实验教师:王志强 学号:20244209 实验日期:2025年3月24日 必修/选修:专选课 1. 实验内容 1.熟悉Python开发环境; 2.练习Python运行、调试技能; 3.编写程序,练习变量和类型、字符串、对象、缩进和注释等; 4.编写一…

E1. Canteen (Easy Version)E2 Canteen (Hard Version) 对于旋转操作的深入理解

E1. Canteen (Easy Version) 题解:二分查找 + 模拟 本文大量学习了jiangly的代码对其进行详细的解析并作图对其进行解释 题目链接 深入解析:前缀和最小值旋转的直观意义一、前缀和曲线的数学本质 我们定义前缀和数组为: pre[i+1] = pre[i] + a[i] - b[i]这一公式的物理意义是…

20244209 2024-2025-2 《Python程序设计》实验一报告

课程:《Python程序设计》 班级: 2442 姓名:韩仕炜 实验教师:王志强 学号:20244209 实验日期:2025年3月24日 必修/选修:专选课 1. 实验内容 1.熟悉Python开发环境; 2.练习Python运行、调试技能; 3.编写程序,练习变量和类型、字符串、对象、缩进和注释等; 4.编写一…

ASP.NET Core WebApi+React UI开发入门详解

在前段时间,有粉丝反馈能否写一篇基于ASP.NET Core Web Api+React UI进行Web开发的文章,经过查阅相关资料,发现Visual Studio 2022已经集成相关模板,可以在Visual Studio中直接创建项目项目,今天以一个小例子,简述ASP.NET Core Web Api+React UI开发系统的基本步骤,仅供…

一文速通Python并行计算:02 Python多线程编程-threading模块、线程的创建和查询与守护线程

本文介绍了Python threading模块的核心功能,包括线程创建与管理、线程状态监控以及守护线程的特殊应用,重点讲解了Thread类的实例化方法、获取当前线程信息、检测线程存活状态,以及如何实现后台线程。一文速通 Python 并行计算:02 Python 多线程编程-threading 模块、线程的…

编程神器Trae:当我用上后,才知道自己的创造力被低估了多少

"AI会让每个人都能成为工具创造者,打破你能力边界,有时候只需要一个想法。" AI粉嫩特攻队,2025年3月23日。 前几天参加了一场行业闭门研讨会,满满1个半小时的干货演讲让我收获颇丰。会后,我迫不及待地想将录音整理成文字,方便日后回顾。却被提示"文件过大…

20244212喻浩川《Python程序设计》实验一报告

课程:《Python程序设计》 班级: 2442 姓名: 喻浩川 学号:20244212 实验教师:王志强 实验日期:2025年3月25日 必修/选修: 公选课 1.实验内容 (1)熟悉Python开发环境; (2)练习Python运行、调试技能; (3)编写程序,练习变量和类型、字符串、对象、缩进和注释等; (4)编写…

龙哥量化:deepseek写公式是需要思路的, 我整理的公式思路,请点赞收藏, 我持续更新ing

龙哥微信:Long622889代写技术指标_选股公式: 通达信,同花顺,东方财富,大智慧,文华,博易,飞狐代写量化策略: TB交易开拓者,文华8,金字塔AI写代码,很多朋友都试过了 deepseek,腾讯元宝,通义千问,豆包,chatgpt,通达信内嵌AI写公式,同花顺内嵌AI写公式,等等,写…

SciTech-EECS-Circuits-电路稳定性: 温度补偿 的几种方式对比: 响应时问、精度、动态范围、线性度、稳定度

电路稳定性: 温度稳定性 测试的几种方式:电吹风加热 冰箱(-5度) + 烤箱(50度/70度)改进 "文氏电桥振荡" 电路 的“热稳定性温度补偿” 网上找来找去,都是用FET(场效应管)做成"压控电阻"控制 "振荡器"的"增益",达到稳幅的目的。 但电…

SpringBoot3+Vue3实现查询功能

安装axios封装前后端对接数据工具npm i axios -S通过requst.js工具类发起请求import axios from "axios"; import {ElMessage} from "element-plus";const request = axios.create({baseURL:http://localhost:8080,//后端统一的请求地址timeout:30000 //后…

Apache Echarts 入门学习 -2025/3/24

介绍 一种数据可视化技术echats官方文档: https://echarts.apache.org/handbook/zh/get-started/ <!DOCTYPE html> <html> <head><meta charset="utf-8"><title>第一个 ECharts 实例</title><!-- 引入 echarts.js --><…