npm vs pnpm 之幽灵依赖

news2024/9/25 1:42:51

在之前的文章📄 果断放弃npm切换到pnpm–节约磁盘空间(256G硬盘救星) 中有提及 npm 扁平化带来的幽灵👻依赖 问题,但没有特别展开,这段时间实际业务中遇到了该问题,特整理如下:

♨️ 问题描述:项目使用 npm 安装依赖可以正常运行,而使用 pnpm 安装依赖运行报错!

以 node-emoji 为例:其是一款表情符号查找和解析工具,它依赖了 @sindresorhus/is 用于值类型检查。

{
  "name": "node-emoji",
  "version": "2.1.3",
  "dependencies": {
    "@sindresorhus/is": "^4.6.0",
    ...
  }
}

🐜 使用 npm/pnpm 新增 node-emoji 依赖

$ npm install node-emoji --save
$ pnpm add node-emoji --save

示例:我 ❤️ 🇨🇳

const emoji = require('node-emoji') 

console.log(emoji.emojify('我 :heart:  :cn:')) 

🐝 均可正常执行,我们修改代码如下:

const emoji = require('node-emoji') 
+ const is = require('@sindresorhus/is')

console.log(emoji.emojify('我 :heart:  :cn:')) 
+ console.log(is('李刚')) // string

⚠️ npm 可正常执行!pnpm 报错:Error: Cannot find module '@sindresorhus/is'

在这里插入图片描述左侧:npm;右侧:pnpm


通过安装的结构,便可以察觉问题:

  • 使用 npm 安装,所有依赖都被提升到了 node_modules 下(npm@3之后的依赖扁平化,解决路径地狱);
  • 使用 pnpm 安装,只有直接依赖(package.json dependences 中声明)安装在 node_modules 下,其他在 .pnpm(扁平化) 目录下。

👉 不再 node_modules 下,所以项目中无法直接引用!

pnpm 好处:

  1. 通过软链的形式,使得 require 可以正常引用;同时对非真正依赖的项目做隔离(避免引用依赖的混乱)

    $ ls -li node_modules/node-emoji                                 
    30559101 lrwxr-xr-x  1 ligang  staff  46  8  6 16:59 node_modules/node-emoji -> .pnpm/node-emoji@2.1.3/node_modules/node-emoji
    
  2. .pnpm 的存在避免了循环引用和层级过深的问题(扁平化)

    node_modules
    └─ .pnpm
    |  ├─ node_modules
    |  |		└─ @sindresorhus+is@4.6.0 -> ../../@sindresorhus+is@4.6.0/node_modules/@sindresorhus/is
    |  ├─ @sindresorhus+is@4.6.0
    |  └─ node-emoji@2.1.3
    |     └─ node_modules  
    |        └─ @sindresorhus/is -> ../../../@sindresorhus+is@4.6.0/node_modules/@sindresorhus/is
    └─ node-emoji
    
  3. 硬链使得不同项目相同依赖只存在一个副本,减少磁盘空间

    $ ll -li node_modules/.pnpm/@sindresorhus+is@4.6.0/node_modules/@sindresorhus/      
    
    30564598 drwxr-xr-x  6 ligang  staff   192B  8  6 17:52 is
    
    inode值文件类型权限链接计数文件拥有者文件群组大小修改日期名称
    30564598drwxr-xr-x6ligangstaff192B8月6日 17:52is

pnpm基于符号链接的 node_modules 结构

硬连接
软连接
inode \n 30564598
file2
file1
inode \n 30559101
file1
file2

解决方案:不推荐

如果缺少依赖太多,可以使用提升选项。此选项官方不推荐。

pnpm install --shamefully-hoist

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux C 程序 【03】线程栈空间

1.开发背景 上一个篇章创建了线程,参考 FreeRTOS,每个线程都是有自己的内存空间,Linux上面也是一样的,这个篇章主要描述线程栈空间的设置。 2.开发需求 设计实验: 1)创建线程,并配置线程内存大…

充电桩--直流充电桩方案详解

一、直流充电桩介绍 1、直流充电桩介绍 电动汽车市场数量的不断激增,为缓解消费者对其里程焦虑与充电焦虑,配置双向OBC可以实现快速充电,还可将电动汽车当作分布式储能站回馈电网帮助消峰填谷,通过DCFC为电动汽车高效充电&#…

【解决错误】ModuleNotFoundError: No module named ‘progress’

【解决错误】ModuleNotFoundError: No module named ‘progress’ 在Python编程中,遇到“ModuleNotFoundError: No module named ‘progress’”这类错误,通常意味着Python解释器在其环境中找不到名为‘progress’的模块。以下将深入探讨这一错误的产生…

HBM2、HBM2E、HBM3和HBM3E技术

HBM(High Bandwidth Memory)是一种高性能的内存技术,主要用于数据中心、超级计算机、高端服务器、图形处理器(GPU)和AI加速器等领域,因为它能够提供比传统DDR内存更高的带宽和更低的功耗。 HBM2、HBM2E、HBM3和HBM3E技术 HBM2 (High Bandwidth Memory 2) HBM2 是HBM技术…

深入JVM:类加载器和双亲委派模型

目录 1. 什么是类加载器2. 类加载器的类型3. 双亲委派模型4. 类装载的过程加载验证准备解析初始化使用卸载 1. 什么是类加载器 如果想要了解什么是类加载器就需要清楚一个Java文件是如何运行的。我们可以看下图: 首先要知道操作系统是不能直接运行Java文件的&#…

大模型Transformer架构详解

深度学习领域正在经历一场剧烈的变革,这得益于Transformer模型的诞生和迅速发展。 这些开创性的架构不仅重新定义了自然语言处理(NLP)的标准,还极大地拓宽了人工智能的多个领域。 凭借其独特的注意力机制和并行处理能力&#xf…

目录的读写

一、文件流和字符描述的转换 1.1、fileno 要求的是内存大小一致 fileno FILE* fp -> int fd fgets(,); int fileno(FILE *stream); 功能: 获得一个文件流指针中的文件描述符 参数: stream:文件流指针 返回值: 成功返回文件描述符 失败返回-1 如果没有特殊要求的&…

如何在Zoom中集成自己的app?一个简单的例子

一、注册zoom 账号、以便在zoom app maketplace创建app。 二、安装git、node.js、vscode开发环境(略)。 三、注册ngrok账号,获得一个免费的https静态域名。 四、配置zoom app(wxl),设置上一步获得的https静态域名,验证…

2024 年 7 月区块链游戏研报:市场波动与数据分化的挑战与机遇

作者:Stella L (stellafootprint.network) 数据来源:Footprint Analytics 游戏研究页面 7 月份,加密货币市场波动显著,价格表现各异。比特币和 Solana 表现抢眼,与此同时,以太坊在美国市场推出现货以太坊…

8.3 字符串中等 306 Additive Number 423 Reconstruct Original Digits from English

306 Additive Number //累加数:除了前两个数,其余数都等于前两个加起来,至少包括三个数 //难点找到前两个数 //条件1:至少包括三个数–>确定前两个数字的最大长度 len n/3 看下方注意1 //条件2:遇到0默认归属于他…

Axure RP界面设计初探:基础操作与实用技巧

Axure RP是目前流行的设计精美的用户界面和交互软件。Axure RP提供了一组丰富的RP。 UI 控件,这些控件根据它们的应用领域进行分类。作为Axure的国产替代品,它可以在线协同工作,浏览器可以在不下载客户端的情况下立即打开和使用。如果以前用A…

护眼灯到底有没有用?一文曝光护眼灯的三大好处!

护眼台灯进入大众的视野,但种类多样,其质量也是参差不齐。不少人一直有着”护眼灯到底有没有用?“质疑,作为学生,课业多且繁重,再加上电子设备普遍普及,眼睛受承受的压力日渐增大。因此&#xf…

如何快速实现MODBUS TCP转Profinet——泗博网关EPN-330

泗博网关EPN-330可作为PROFINET从站,支持与西门子S7-200 SMART/300/400/1200/1500全系列PLC以及具有PROFINET主站的系统无缝对接,而Modbus TCP端,可以与Modbus TCP从站设备、主站PLC、DCS系统以及组态软件等进行数据交互。 通过EPN-330&…

【算法设计题】编写算法,统计带头节点的单链表L的实际元素个数,第5题(C/C++)

目录 第5题 统计带头节点的单链表L的实际元素个数 得分点(必背) 题解:统计带头节点的单链表L的实际元素个数 代码解答 详细解释 举例说明 🌈 嗨,我是命运之光! 🌌 2024,每日百…

第二证券:沪指涨0.31%,电力、煤炭等板块拉升,卫星导航概念活跃

7日早盘,沪指盘中发力上扬,深证成指、创业板指震荡翻绿,场内超2700只个股飘绿。 到午间收盘,沪指涨0.31%报2876.17点,深证成指跌0.04%,创业板指跌0.16%,上证50指数涨0.34%,两市算计…

Leetcode每日刷题之字符串相加(C++)

在学习的同时也不要忘记适当练习,本题字符串相加主要在于字符串类型与整数类型的转化,要将字符串类型转化为整数类型计算后转化为字符串类型输出即可。 思路解析 根据题中给出的信息,我们不可以使用库函数计算大整数,也不能直接将…

代码随想录算法训练营第四天(二)|面试题 02.07. 链表相交 142.环形链表II

面试题 02.07. 链表相交 题目: 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。 图示两个链表在节点 c1 开始相交: 题目数据 保证 整个链式结构中不存在环…

视频号直播回放怎么下载?

一、如果是下载自己直播回放视频: 方法一:视频号助手 打开网址:视频号助手 登陆账号后。下面路径,先点击成回放, 后就可以在下面路径,下载全场回放 但是这种有个缺点,就是不能分段下载。这样…

C语言----计算开机时间

计算开机时间 实例说明 编程实现计算开机时间&#xff0c;要求在每次开始计算开机时间时都能接着上次记录的结果向下记录。 实现过程&#xff1a; 1. 在TC中创建一个C文件。 2. 引用头文件&#xff0c;代码如下: #include <stdio.h> 3. 定义结构体time&#xff0c;用来…

AI绘画 | Stable Diffusion后期处理—无需ControlNet也能轻松高清放大图像与老旧照片修复,SD新手必看教程

大家好&#xff0c;我是画画的小强 分享了这么多期AI绘画Stable DIffusion的入门教程和一些常用的插件玩法后&#xff0c;不知道大家有没有发现&#xff0c;SD还有一个功能&#xff0c;似乎没怎么用到过&#xff0c;它就是—后期处理。 今天就给大家分享一下SD中的 “后期处理…