首页 > 解决方案 > 当多个版本需要同一个模块时,NodeJS 如何处理模块缓存

问题描述

对于具有以下结构的项目:

  index.js => require('debug')
           => require('express')
  node_modules
    debug => version 3.x.x
    express => require('debug')
      node_modules
        debug => version 2.x.x
  1. NodeJS 加载 index.js 中需要的调试模块,有 3.xx 版本
  2. 当为 express 模块加载调试模块时,NodeJS 是使用已经缓存的调试模块(v3.xx)还是加载 express 模块所需的调试模块(2.xx)?

标签: node.js

解决方案


模块缓存不仅仅是根文件名,它是完全解析的路径。

因此,如果模块“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 的完整路径。


推荐阅读