当前位置: 首页 > article >正文

pnpm解决幽灵依赖问题

文章目录

  • 前言
      • 1. npm/yarn 现在还有幽灵依赖问题吗?
      • 2. pnpm 解决了幽灵依赖问题吗?
      • 3. pnpm 是如何解决的?
        • 举例说明
    • 1. pnpm 的 node_modules 结构原理
      • 结构示意
    • 2. 实际演示幽灵依赖的杜绝
      • 步骤1:初始化项目并安装依赖
      • 步骤2:在代码中引入未声明的依赖
      • 步骤3:运行代码
    • 3. 查看 pnpm 的 node_modules 结构
    • 4. 总结


前言

1. npm/yarn 现在还有幽灵依赖问题吗?

有。

  • npm(包括 v9)和 yarn(classic/berry)默认依然采用“扁平化 node_modules”结构。
  • 只要依赖被扁平化安装到顶层 node_modules,项目代码就可以直接 require/导入未在本项目 package.json 声明的依赖(即幽灵依赖)。
  • 只要依赖树发生变化(比如间接依赖被移除),你的代码就会因为找不到依赖而报错。

2. pnpm 解决了幽灵依赖问题吗?

pnpm 基本解决了这个问题。

  • pnpm 采用了“严格的 node_modules 隔离”机制(hoisting less,严格依赖树)。
  • 每个包只能访问自己 package.json 里声明的依赖,不能直接 require 间接依赖。
  • 如果你在代码里 require 了未声明的依赖,pnpm 安装后运行会直接报错(找不到模块)。

3. pnpm 是如何解决的?

  • pnpm 在 node_modules 下采用了“软链接+隔离”结构。
  • 每个包的 node_modules 只包含自己声明的依赖(通过 symlink 指向全局 store),不会自动把所有依赖都扁平化到顶层。
  • 这样,只有在 package.json 里声明的依赖才能被 require 到,未声明的依赖不会被自动暴露出来。
举例说明

假设你的 package.json 没有声明 moment,但代码里用了:

const moment = require('moment');
  • 用 npm/yarn 安装,如果有其他依赖间接依赖了 moment,代码可能能跑。
  • 用 pnpm 安装,运行时会直接报错:Cannot find module 'moment'

1. pnpm 的 node_modules 结构原理

  • pnpm 不像 npm/yarn 那样把所有依赖都“扁平化”到顶层 node_modules。
  • pnpm 会在项目的 node_modules 下为每个包建立一个“虚拟隔离环境”,每个包只能访问自己 package.json 里声明的依赖。
  • 具体实现方式是:pnpm 在 node_modules 里用符号链接(symlink)指向全局 store 里的真实包内容,并且只为声明的依赖建立链接。

结构示意

假设你的项目结构如下:

project/node_modules/.pnpm/react@18.1.0/lodash@4.17.21/react -> .pnpm/react@18.1.0/node_modules/reactlodash -> .pnpm/lodash@4.17.21/node_modules/lodashfooter/node_modules/react -> ../../../.pnpm/react@18.1.0/node_modules/react
  • .pnpm 目录存放所有真实包内容。
  • node_modules/react 是指向 .pnpm/react@18.1.0/node_modules/react 的符号链接。
  • 每个包(如 footer)自己的 node_modules 只包含自己声明的依赖的链接。

2. 实际演示幽灵依赖的杜绝

步骤1:初始化项目并安装依赖

pnpm install

步骤2:在代码中引入未声明的依赖

假设 footer 包的 package.json 没有声明 moment,但你在代码里写了:

const moment = require('moment');

步骤3:运行代码

pnpm run start

结果:

Error: Cannot find module 'moment'

pnpm 会直接报错,因为 footer 的 node_modules 里没有 moment 的符号链接。


3. 查看 pnpm 的 node_modules 结构

你可以用如下命令查看符号链接结构:

tree /F node_modules

在 Windows 的 cmd 终端中,你可以使用 cd 命令切换到指定目录。
具体命令如下:

cd /d d:\js\getting-started-example

/d 参数用于切换驱动器(比如从 C: 切换到 D:)。

你会发现只有声明的依赖才会出现在每个包的 node_modules 里,未声明的依赖不会被暴露出来。


4. 总结

  • pnpm 通过“符号链接+隔离”机制,保证每个包只能访问自己声明的依赖,彻底杜绝了幽灵依赖。

  • 这样可以极大提升依赖安全性和可维护性,适合大型 Monorepo 项目。

  • npm/yarn:幽灵依赖问题依然存在,需靠开发者自律和工具检测(如 depcheck)。

  • pnpm:通过 node_modules 隔离机制,从根本上杜绝了幽灵依赖,强制每个包声明自己的依赖。

相关文章:

pnpm解决幽灵依赖问题

文章目录 前言1. npm/yarn 现在还有幽灵依赖问题吗?2. pnpm 解决了幽灵依赖问题吗?3. pnpm 是如何解决的?举例说明 1. pnpm 的 node_modules 结构原理结构示意 2. 实际演示幽灵依赖的杜绝步骤1:初始化项目并安装依赖步骤2&#xf…...

测试第四课---------性能测试工具

作者前言 🎂 ✨✨✨✨✨✨🍧🍧🍧🍧🍧🍧🍧🎂 ​🎂 作者介绍: 🎂🎂 🎂 🎉🎉&#x1f389…...

frp远程穿透配置

文章目录 准备工作服务端配置(toml)客户端配置(toml)访问内网服务使用ini文件配置 frp是一个高性能的反向代理应用,用于将位于内网的服务通过代理暴露到公网。以下是其基本使用步骤: 准备工作 拥有一台具有公网IP的服务器,作为frp的服务端。…...

【C++】新手入门指南(下)

文章目录 前言 一、引用 1.引用的概念和定义 2.引用的特性 3.引用的使用 4.const引用 5.指针和引用的关系 二、内联函数 三、nullptr 总结 前言 这篇续上篇的内容新手入门指南(上),继续带大家学习新知识。如果你感兴趣欢迎订购本专栏。 一、…...

Linux系统编程 day9 SIGCHLD and 线程

SIGCHLD信号 只要子进程信号发生改变&#xff0c;就会产生SIGCHLD信号。 借助SIGCHLD信号回收子进程 回收子进程只跟父进程有关。如果不使用循环回收多个子进程&#xff0c;会产生多个僵尸进程&#xff0c;原因是因为这个信号不会循环等待。 #include<stdio.h> #incl…...

前后端分离项目在未部署条件下如何跨设备通信

其实我此前也不知道这个问题怎么解决&#xff0c;也没有想过—因为做的项目大部分都是前后端分离的&#xff0c;前端直接用后端的部署好的环境就行了。最近也是有点心高气傲开始独立开发&#xff0c;一个人又写前端又写后端也是蛮累的&#xff0c;即使有强有力的cursor也很累很…...

基于Python的多光谱遥感数据处理与分类技术实践—以农作物分类与NDVI评估为例

多光谱遥感数据包含可见光至红外波段的光谱信息&#xff0c;Python凭借其丰富的科学计算库&#xff08;如rasterio、scikit-learn、GDAL&#xff09;&#xff0c;已成为处理此类数据的核心工具。本文以Landsat-8数据为例&#xff0c;演示‌辐射校正→特征提取→监督分类→精度评…...

vscode python 代码无法函数跳转的问题

TL; DR; python.languageServer 配置成了 None 导致 vscode python 代码无法函数跳转 详细信息 mac 环境下 vscode 正常 command 鼠标左键 可以跳转到定义或者使用位置&#xff0c;但是我的为何不知道失效了 我一开始以为是热键冲突&#xff0c;结果发现 mac 好像没办法定…...

SAS宏核心知识与实战应用

1. SAS宏基础 1.1 核心概念 1.1.1 宏处理器 宏处理器在SAS程序运行前执行,用于生成动态代码,可实现代码的灵活定制。 通过宏处理器,可基于输入参数动态生成不同的SAS代码,提高代码复用性。 1.1.2 宏变量 宏变量是存储文本值的容器,用&符号引用,如&var,用于存储…...

Unity 脚本使用(二)——UnityEngine.AI——NavMesh

描述 Singleton class 用于访问被烘培好的 NavMesh. 使用NavMesh类可以执行空间查询&#xff08;spatial queries&#xff09;&#xff0c;例如路径查找和可步行性测试。此类还允许您设置特定区域类型的寻路成本&#xff0c;并调整寻路和避免的全局行为。 静态属性&#xff0…...

从项目真实场景中理解二分算法的细节(附图解和模板)

遇到一个真实场景里使用二分算法的问题&#xff0c;本以为可以放心交给小师弟去做&#xff0c;结果出现了各种问题&#xff0c;在此梳理下二分算法的核心思想和使用细节。 文章目录 1.场景描述2.场景分析3.二分算法的精髓3.1 核心模板3.2 二分过程图解3.3 各种区间写法3.3.1 闭…...

金融图QCPFinancial

QCPFinancial 是 QCustomPlot 中用于绘制金融图表&#xff08;如蜡烛图/K线图&#xff09;的核心类。以下是其关键特性的详细说明&#xff1a; 一、主要属性 属性类型说明dataQSharedPointer<QCPFinancialDataContainer>存储金融数据的数据容器chartStyleQCPFinancial:…...

Jetson Orin NX 16G 配置GO1强化学习运行环境

这一次收到了Jrtson Orin NX, 可以进行部署了。上一次在nano上的失败经验 Jetson nano配置Docker和torch运行环境_jetson docker-CSDN博客 本次的目的是配置cuda-torch-python38环境离机运行策略。 Jetson Orin NX SUPER 1. 烧录镜像 参考链接在ubuntu系统中安装sdk manag…...

文档管理 Document Management

以下是关于项目管理中 文档管理 的深度解析,结合高项(如软考高级信息系统项目管理师)教材内容,系统阐述文档管理的理论框架、核心流程及实战应用: 一、文档管理的基本概念 1. 定义 文档管理是对项目全生命周期中产生的各类文档进行规范化管理的过程,包括创建、存储、版…...

【Pandas】pandas DataFrame truediv

Pandas2.2 DataFrame Binary operator functions 方法描述DataFrame.add(other)用于执行 DataFrame 与另一个对象&#xff08;如 DataFrame、Series 或标量&#xff09;的逐元素加法操作DataFrame.add(other[, axis, level, fill_value])用于执行 DataFrame 与另一个对象&…...

Linux 内核中 cgroup 子系统 cpuset 是什么?

cpuset 是 Linux 内核中 cgroup&#xff08;控制组&#xff09; 的一个子系统&#xff0c;用于将一组进程&#xff08;或任务&#xff09;绑定到特定的 CPU 核心和 内存节点&#xff08;NUMA 节点&#xff09;上运行。它通过限制进程的 CPU 和内存资源的使用范围&#xff0c;优…...

Windows 同步-互锁变量访问

互锁变量访问 应用程序必须同步对多个线程共享的变量的访问。 应用程序还必须确保对这些变量的作以原子方式执行&#xff08;完全或根本不执行&#xff09;。 对正确对齐的 32 位变量的简单读取和写入是原子作。 换句话说&#xff0c;你最终不会只更新变量的一部分;所有位都以…...

深度学习3.5 图像分类数据集

%matplotlib inline import torch import torchvision from torch.utils import data from torchvision import transforms from d2l import torch as d2l代码执行流程图 #mermaid-svg-WWhBmQvijswiICpI {font-family:"trebuchet ms",verdana,arial,sans-serif;font-…...

js原型链prototype解释

function Person(){} var personnew Person() console.log(啊啊,Person instanceof Function);//true console.log(,Person.__proto__Function.prototype);//true console.log(,Person.prototype.__proto__ Object.prototype);//true console.log(,Function.prototype.__prot…...

从M个元素中查找最小的N个元素时,使用大顶堆的效率比使用小顶堆更高,为什么?

我们有一个长度为 M 的数组&#xff0c;现在我们想从中找出 最小的 N 个元素。例如&#xff1a; int a[10] {12, 3, 5, 7, 19, 0, 8, 2, 4, 10};从中找出 最小的 4 个元素。 正确方法&#xff1a;使用大小为 N 的「大顶堆」 原因分析&#xff1a; 我们想保留最小的 4 个元素…...

【知识】性能优化和内存优化的主要方向

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 前言 现在有很多论文&#xff0c;乍一看很高级&#xff0c;实际上一搜全是现有技术的堆砌&#xff0c;但是这种裁缝式的论文依然能发表在很好的会议和期…...

VS Code + GitHub:高效开发工作流指南

目录 一、安装 & 基本配置 1.下载 VS Code 2.安装推荐插件(打开侧边栏 Extensions) 3.设置中文界面(可选) 二、使用 VS Code 操作 Git/GitHub 1.基本 Git 操作(不输命令行!) 2.连接 GitHub(第一次使用) 三、克隆远程仓库到 VS Code 方法一(推荐): 方…...

软件测试之接口测试常见面试

一、什么是(软件)接口测试? 接口测试&#xff1a;是测试系统组件间接口的一种测试方法 接口测试的重点&#xff1a;检查数据的交换&#xff0c;数据传递的正确性&#xff0c;以及接口间的逻辑依赖关系 接口测试的意义&#xff1a;在较早期开展&#xff0c;在软件开发的同时…...

发送百度地图的定位

在vuephp写的聊天软件项目中&#xff0c;增加一个发送百度地图的定位功能 在 Vue PHP 的聊天软件中增加发送百度地图定位功能&#xff0c;需要从前端定位获取、地图API集成、后端存储到消息展示全流程实现。以下是详细步骤&#xff1a; 一、前端实现&#xff08;Vue/Uni-app…...

11、Refs:直接操控元素——React 19 DOM操作秘籍

一、元素操控的魔法本质 "Refs是巫师与麻瓜世界的连接通道&#xff0c;让开发者能像操控魔杖般精准控制DOM元素&#xff01;"魔杖工坊的奥利凡德先生轻抚着魔杖&#xff0c;React/Vue的refs能量在杖尖跃动。 ——以神秘事务司的量子纠缠理论为基&#xff0c;揭示DOM…...

uniapp-商城-33-shop 布局搜索页面以及u-search

shop页面上有一个搜索&#xff0c;可以进行商品搜索&#xff0c;这里我们先做一个页面布局&#xff0c;后面再来进行数据i联动。 1、shop页面的搜索 2、搜索的页面代码 <navigator class"searchView" url"/pagesub/pageshop/search/search"> …...

npm的基本使用安装所有包,安装删除指定版本的包,配置命名别名

npm的基本使用安装所有包&#xff0c;安装删除指定版本的包&#xff0c;配置命名别名 安装所有依赖指定版本安装/删除包给 npm 脚本配置“命令别名&#xff08;自定义命令&#xff09;” ✅ 一、安装所有包&#xff08;恢复依赖&#xff09; 如果项目中已经存在 package.json…...

【dataframe显示不全问题】打开一个行列超多的excel转成df之后行列显示不全

出现问题如下图&#xff1a; 解决方案&#xff5e; display.width解决列显示不全 pd.set_option(display.max_columns,1000) pd.set_option(display.width, 1000) pd.set_option(display.max_colwidth,1000) pd.set_option(display.max_rows,1000)...

Windows下Golang与Nuxt项目宝塔部署指南

在Windows下将Golang后端和Nuxt前端项目打包&#xff0c;并使用宝塔面板部署的步骤如下 一、Golang后端打包 交叉编译为Linux可执行文件 在Windows PowerShell中执行&#xff1a; powershell复制下载 $env:GOOS "linux" $env:GOARCH "amd64" go build…...

真实趋势策略思路

该交易策略通过一系列技术指标的计算与逻辑判断&#xff0c;旨在捕捉市场趋势的反转与延续点&#xff0c;以实现盈利。其主要交易逻辑思路可以概括如下&#xff1a; 1. 趋势与动量分析 策略首先利用动量函数计算收盘价的短期&#xff08;3周期&#xff09;变化&#xff0c;通过…...