node.js - 当多个版本需要同一个模块时,NodeJS 如何处理模块缓存
问题描述
对于具有以下结构的项目:
index.js => require('debug')
=> require('express')
node_modules
debug => version 3.x.x
express => require('debug')
node_modules
debug => version 2.x.x
- NodeJS 加载 index.js 中需要的调试模块,有 3.xx 版本
- 当为 express 模块加载调试模块时,NodeJS 是使用已经缓存的调试模块(v3.xx)还是加载 express 模块所需的调试模块(2.xx)?
解决方案
模块缓存不仅仅是根文件名,它是完全解析的路径。
因此,如果模块“A”正在加载 index.js 的 v3.xx,而模块“B”正在从不同的磁盘位置加载 index.js 的 v2.xx,那么两者都会被加载,因为模块缓存会将它们识别为不同的文件并将它们分别缓存。
因此,由于 v3.xx 和 v2.xxindex.js
不可能存在于相同的完整路径中,因此整个系统工作得很好,因为每个模块都可以require()
在它附带的每个依赖模块的精确版本中。
这假设模块表现良好并且没有做可能破坏这种能力的事情,例如建立可能冲突的全局变量或竞争共享资源的锁定等......如果它们是表现良好的模块,那么项目可以拥有一个模块使用 v3.xx,另一个模块使用 v2.xx。这是通过每个模块的单独范围以及每个依赖模块分别导入它们的能力来实现的。
我在nodejs文档中读到了这一点,我不清楚“相同文件”是什么意思。它是相同的文件名,相同的文件绝对路径,相同的文件内容吗?
这是相同的完整路径,例如:
/whatever/user/someUser/myProject/node_modules/index.js
将是 index.js 的完整路径。
如果您没有指定完整路径require()
,require('index.js');
或者您指定了相对路径,那么它将是require()
根据指定的搜索规则require()
(如文档中指定的)找到 index.js 的完整路径。
推荐阅读
- angular - 如何使用 Angular 在 Pingfed 中注销
- ruby-on-rails - 在 Stream Rails 中的两个提要组中创建活动
- android - Android Studio 按钮 onClickListener 无法切换布局
- c++ - 通过对数组成员的越界访问来访问类成员
- google-cloud-platform - 在 GCP - Google Cloud Console 中进行更改时,有没有办法查看 gcloud cli 的相应命令?
- swift - 试图在函数中返回不同的形状。错误:函数声明了一个不透明的返回类型
- python - 在 python 虚拟环境之间切换
- asp.net - Soap 标头异常意外元素
- node.js - 批准节点js中的支付网关集成
- r - 在R中按变量扩展列但保留原始变量?