简单认识 node 包的幽灵依赖

幽灵依赖的概念与成因

在 Node.js 的包管理生态系统中,特别是使用 npm(Node Package Manager)作为包管理器时,“幽灵依赖”是指那些没有直接在项目的 dependenciesdevDependencies 中显式声明,但却能够在项目的依赖树中找到并使用的模块。这种现象主要源于以下几个方面:

  1. Node.js 的模块解析规则: Node.js 采用了一种非传统的模块加载机制,允许模块在其父目录以及祖先目录的 node_modules 目录中查找依赖。当两个或更多的直接依赖间接依赖同一个模块但版本要求不同时,可能会在更高层级的 node_modules 目录中出现一个版本,这个版本虽未被项目直接声明,却会被依赖树中的其他模块使用,形成“幽灵依赖”。
  2. npm 的扁平化安装策略: 早期 npm 安装依赖时遵循树状结构,即每个依赖包的 node_modules 目录中包含其所有子依赖。后来为了减少磁盘空间占用和降低模块加载复杂度,npm 引入了扁平化(或称拉平)安装策略,使得相同模块只在最顶层的 node_modules 目录中保留一个实例。这种策略可能导致某些模块虽然未被项目直接引用,但由于被多个直接依赖共享,从而成为项目依赖树的一部分。
  3. 间接依赖的变动: 当直接依赖更新时,它们可能引入新的间接依赖或者升级已有间接依赖的版本,导致项目中出现了未经显式声明但在运行时被使用的模块版本,形成“幽灵依赖”。

影响与挑战

幽灵依赖带来了一些潜在问题和挑战:

  • 版本不确定性: 由于未在项目配置中明确指定,幽灵依赖的版本控制变得困难,可能导致项目构建或运行时使用了开发者意料之外的模块版本,引发兼容性问题或行为差异。
  • 安全风险: 隐藏的依赖可能包含已知漏洞,而在常规的依赖管理和审计过程中容易被忽视,增加了项目的安全风险。
  • 维护困难: 当出现问题时,定位和管理幽灵依赖较为困难,因为它们并不直接体现在 package.json 文件中。

应对策略

为了解决幽灵依赖带来的问题,npm 提供了以下机制和最佳实践:

  • lockfiles(锁定文件):package-lock.jsonnpm-shrinkwrap.json,用于记录安装时确切的模块版本及依赖树状态。这些文件确保了项目在不同环境和时间点的重复安装都能得到一致的依赖版本,有效减少了幽灵依赖引起的不确定性。
  • 依赖审计工具: 使用诸如 npm audit 或第三方安全扫描工具,定期检查项目依赖是否存在已知漏洞,包括幽灵依赖在内的所有模块都会被纳入审计范围。
  • 明确依赖声明: 对于项目确实需要的功能或修复,应尽可能将其对应的依赖显式添加到 dependenciesdevDependencies 中,避免依赖于间接引入的模块版本。
  • 保持依赖更新: 定期更新项目依赖并重新生成 lockfile,以获取安全更新和功能改进,同时监控是否有新的幽灵依赖产生。

总结

简单来说,就是由于 npm 将所有层级的依赖都直接扁平式地放在 node_modules 文件夹中了。这种机制的结果就是,允许模块直接从父文件夹,也就是 node_modules 中直接获取依赖。这个时候问题就来了。

比如我们只安装了一个 express 包,但你会发现 node_modules 中却有十几个子文件夹。这些子文件夹(也就是模块)并没有在我们的 package.json 文件中声明,但其他的模块却可以获取到这些模块。如果在这个过程中有某个模块拿错了东西,那么就会导致错误,而这个错误我们是很难找到的,因为对于我们而言,我们仅仅只是安装了 express!

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

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

相关文章

LCD1602显示屏

LCD1602显示 概述 LCD1602(Liquid Crystal Display)是一种工业字符型液晶,能够同时显示 1602 即 32 字符(16列两行) 引脚说明 //电源 VSS -- GND VDD -- 5V //对比度 VO -- GND //控制线 RS -- P1.0 RW -- P1.1 E -- P1.4 //背光灯 A -- 5…

LLaMA-Factory+qwen多轮对话微调

LLaMA-Factory地址:https://github.com/hiyouga/LLaMA-Factory/blob/main/README_zh.md qwen地址:https://huggingface.co/Qwen/Qwen-7B-Chat/tree/main 数据准备 数据样例 [ {"id": "x3959", "conversations": [{&qu…

2024年150道高频Java面试题(十六)

31. Java 8 中引入的 Stream API 有哪些用途? Java 8 中引入的 Stream API 是一个强大的新特性,它提供了一种高效且易于使用的处理数据的方法。Stream API 的用途主要包括以下几个方面: 简化集合操作:Stream API 可以对集合对象…

在ChatGPT中,能用DALL·E 3编辑图片啦!

4月3日,OpenAI开始向部分用户,提供在ChatGPT中的DALLE 3图片编辑功能。 DALLE 3是OpenAI在2023年9月20日发布的一款文生图模型,其生成的图片效果可以与Midjourney、leonardo、ideogram等顶级产品媲美,随后被融合到ChatGPT中增强其…

matlab的歧视:simulink不能使用stm32f4系列的ADC?

2023b的matlab,stm32f407芯片,运行内容Using the Analog to Digital Converter Block to Support STMicroelectronics STM32 Processor Based Boards Using the Analog to Digital Converter Block to Support STMicroelectronics STM32 Processor Base…

基于SSM的社区疫情防控管理信息系统

目录 背景 技术简介 系统简介 界面预览 背景 随着时代的进步,计算机技术已经全方位地影响了社会的发展。随着居民生活质量的持续上升,人们对社区疫情防控管理信息系统的期望和要求也在同步增长。在社区疫情防控日益受到广泛关注的背景下&#xff0c…

【漏洞复现】通天星CMSV6车载主动安全监控云平台inspect_file接口处存在任意文件上传漏洞

免责声明:文章来源互联网收集整理,请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该…

电商技术揭秘一:电商架构设计与核心技术

文章目录 引言一、电商平台架构概述1.1 架构设计原则与架构类型选择1.2 传统电商平台架构与现代化架构趋势分析 二、高并发处理与负载均衡2.1 高并发访问特点分析与挑战2.2 负载均衡原理与算法选择 三、分布式数据库与缓存技术3.1 分布式数据库设计与一致性考量3.2 缓存策略与缓…

第四十二章 保护与 IRIS 的 Web 网关连接 - Windows

文章目录 第四十二章 保护与 IRIS 的 Web 网关连接 - WindowsKerberos 的 Windows Web 网关配置 Kerberos 的 UNIX Web 网关配置Kerberos 的 UNIX Web 网关配置基于 SSL/TLS 的身份验证和数据保护 第四十二章 保护与 IRIS 的 Web 网关连接 - Windows Kerberos 密钥表未针对 Wi…

Vue登陆鉴权方案(token)

Vue token 登陆鉴权完整方案-----总结 一、路由拦截 目的:页面跳转时验证,确认是否即将进入的页面需要登陆验证。 router/index.js //给需要验证的页面添加 meta : { requireAuth :true } 如下: export default new Router({scrollBehavior…

基于SpringBoot和Vue的金融融资管理系统的设计和实现【附源码】

1、系统演示视频(演示视频) 2、需要交流和学习请联系

vue弹出的添加信息组件中 el-radio 单选框无法点击问题

情景描述:在弹出的添加信息的组件中的form中有一个单选框,单选框无法进行点击切换 原因如下: 单选框要求有个默认值,因为添加和更新操作复用同一个组件,所以我在初始化时对相关进行了判定,如果为空则赋初始值 结果这样虽然实现了初始值的展示,但是就是如此造成了单选框的无法切…

Java Web面试题(四)

1. JDBJDBC的DriverManager主要用于管理一组JDBC驱动程序。其主要职责包括: JDBC的DriverManager主要用于管理一组JDBC驱动程序。其主要职责包括: 注册数据库驱动程序:在使用JDBC连接数据库之前,必须先注册适用于数据库的驱动程…

代码随想录算法训练营第二十九天(回溯5)|491. 非递减子序列、46. 全排列、47. 全排列 II(JAVA)

文章目录 491. 非递减子序列解题思路源码 46. 全排列解题思路源码 47. 全排列 II解题思路源码 总结 491. 非递减子序列 给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 …

Java基础学习: Forest - 极简 HTTP 调用 API 框架

文章目录 一、介绍参考: 一、介绍 Forest是一个开源的Java HTTP客户端框架,专注于简化HTTP客户端的访问。它是一个高层的、极简的轻量级HTTP调用API框架,通过Java接口和注解的方式,将复杂的HTTP请求细节隐藏起来,使HT…

前端返回 List<Map<String, Object>>中的vaue值里面包含一个Bigdecimal类型,序列化时小数点丢失,如何解决?

🏆本文收录于「Bug调优」专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&…

golang channel实践代码及注意事项

在使用Go语言(Golang)的通道(Channel)时,有几个重要的注意点可以帮助开发者更安全、高效地使用它们进行并发编程。以下是一些关键的注意事项: 选择正确的通道类型:Go语言提供了两种类型的通道&…

Linux 命令 top 详解

1 top命令介绍 Linux系统中,Top命令主要用于实时运行系统的监控,包括Linux内核管理的进程或者线程的资源占用情况。这个命令对所有正在运行的进程和系统负荷提供不断更新的概览信息,包括系统负载、CPU利用分布情况、内存使用、每个进程的内容…

PS从入门到精通视频各类教程整理全集,包含素材、作业等(7)

PS从入门到精通视频各类教程整理全集,包含素材、作业等 最新PS以及插件合集,可在我以往文章中找到 由于阿里云盘有分享次受限制和文件大小限制,今天先分享到这里,后续持续更新 PS敬伟01——90集等文件 https://www.alipan.com/s…

Golang | Leetcode Golang题解之第7题整数反转

题目&#xff1a; 题解&#xff1a; func reverse(x int) (rev int) {for x ! 0 {if rev < math.MinInt32/10 || rev > math.MaxInt32/10 {return 0}digit : x % 10x / 10rev rev*10 digit}return }