npm vs pnpm 之幽灵依赖

ops/2024/10/22 17:22:46/

在之前的文章📄 果断放弃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.ppmy.cn/ops/93077.html

相关文章

【项目实战】C++视频共享点播系统

目录 一、项目介绍 1.1 对视频共享点播系统的认识 1.2服务端程序负责功能 1.3 服务端功能模块划分 1.4 项目界面演示 1.5预备知识 二.环境搭建 2.1 安装 Jsoncpp 库 2.1.1 使用jsoncpp 2.2 引入httplib库 2.2.1 安装Git(如果你的系统尚未安装Git&#xf…

【C#】StringComparer

什么是“文化” 在 .NET 中,“文化”(Culture)指的是与语言、地区、和区域设置相关的特定信息集合。这些信息包括了日期和时间的格式、数字的表示方式、货币符号、字符串比较规则等等。文化的概念在软件开发中特别重要,因为应用程…

10步搞定Python爬虫从零到精通!

学习Python网络爬虫可以分为以下几个步骤,每一步都包括必要的细节和示例代码,以帮助你从零开始掌握这一技能。 第一步:理解网络爬虫基础 什么是网络爬虫? 网络爬虫是一种自动化程序,用来从互联网上收集数据.它通过发送 HTTP 请求…

【Python_PySide6学习笔记(三十七)】清空QLayout中所有控件的方法

清空QLayout中所有控件的方法 清空QLayout中所有控件的方法前言正文1、takeAt()方法2、自定义f_clearLayoutFunc()方法3、setParent(None)方法 清空QLayout中所有控件的方法 前言 在 GUI 开发中,当我们使用 PySide6(或兼容的PyQt6)的 QVBox…

Vue-04.指令-v-if和v-show

v-if v-else v-else-if 条件性的渲染某元素,判定为true时渲染,否则不渲染 v-show 根据条件展示某元素,区别在于切换的是display属性的值 v-if在浏览器中element标签中如果不满足条件就不会渲染展示…

【Datawhale AI夏令营第四期】 魔搭-大模型应用开发方向笔记 Task01 DeepSeek简易AI助手

【Datawhale AI夏令营第四期】 魔搭-大模型应用开发方向 Task01 正处于拿毕业证求职和实习离职期间的过渡期,想着闲着也是闲着,索性拉上本科同学队友报名参加AI比赛,想方设法卷个项目经验出来。 Task1的任务主要是体验从0开始搭建一个AI对…

【AI】算力底座的巨变

生成式 AI 的迅猛演进,推动 AI 基础设施(AI Infra)加速发展,增长趋势将从大模型专业领域延伸至各行业领域,AI Infra“质量双螺旋”的发展模式将逐步形成,单集群从万卡“量变”至十万卡的同时,集…

电脑文件加密怎么设置?手把手一步一步教给你

电脑文件加密是保护个人隐私和敏感信息的重要手段,可以通过多种方法实现。以下是一些常用的电脑文件加密设置方法,包括使用安企神加密软件的步骤。 一、电脑文件加密的通用方法 1.Windows系统自带加密功能: 选中需要加密的文件或文件夹&…