nodejs中具有相似名称的依赖项的需求优先级
Priority of require for dependencies with similar names in nodejs
今天我在 nodejs 应用程序中遇到了一个错误,我找到了根本原因,但我找不到指定此行为的文档,而且我的在线搜索没有产生太多结果。所以我正在寻找可以明确解释为什么会发生这种情况的资源。我认为它在网上某个地方,但我错过了正确的关键字来找到我要找的东西。
为了解释这种情况,假设我有以下目录树。请注意如何将三个对象导入为 config
:
.
├ config
│ └ index.js # Exports a simple object: `module.exports = { file: "config/index.js" };`
├ config.js # Exports a another object: `module.exports = { file: "config.js" };`
├ config.json # Contains a different json: `{ "file": "config.json" }`
└ module
└ index.js
现在在 module/index.js
如果我 require
其他三个文件中的任何一个明确地一切都按预期进行:
console.log(require("../config.js")); // { file: 'config.js' }
console.log(require("../config.json")); // { file: 'config.json' }
console.log(require("../config/index.js")); // { file: 'config/index.js' }
我需要解释的行为是当我 require('../config')
没有指定确切的文件时。从我的测试来看,优先级似乎是这样的:
- 首先尝试导入
config.js
- 然后尝试导入
config.json
- 如果 none 存在,请尝试导入
config/index.js
但是我找不到任何可以明确指定此行为的资源。我阅读了 this nodejs doc 但找不到有关此特定行为的规范。我在哪里可以了解有关 require
对类似模块名称应用的优先顺序的更多信息?
require()
的规则和优先级已经非常清楚 here in the nodejs doc。
开头是这样的:
require(X) from module at path Y
1. If X is a core module,
a. return the core module
b. STOP
2. If X begins with '/'
a. set Y to be the filesystem root
3. If X begins with './' or '/' or '../'
a. LOAD_AS_FILE(Y + X)
b. LOAD_AS_DIRECTORY(Y + X)
c. THROW "not found"
4. If X begins with '#'
a. LOAD_PACKAGE_IMPORTS(X, dirname(Y))
5. LOAD_PACKAGE_SELF(X, dirname(Y))
6. LOAD_NODE_MODULES(X, dirname(Y))
7. THROW "not found"
由于第 1 步或第 2 步均不适用,但第 3 步确实适用,因此它将首先尝试使用 LOAD_AS_FILE(Y + X)
的 3a。
而且,LOAD_AS_FILE
看起来像这样:
LOAD_AS_FILE(X)
1. If X is a file, load X as its file extension format. STOP
2. If X.js is a file, load X.js as JavaScript text. STOP
3. If X.json is a file, parse X.json to a JavaScript Object. STOP
4. If X.node is a file, load X.node as binary addon. STOP
从那里,您可以看到您观察到的优先级是先查找 config.js
,然后是 config.json
。
只有当这两个都失败时,它才会转到步骤 3b LOAD_AS_DIRECORY(Y+X)
,在那里它会找到 index.js
.
今天我在 nodejs 应用程序中遇到了一个错误,我找到了根本原因,但我找不到指定此行为的文档,而且我的在线搜索没有产生太多结果。所以我正在寻找可以明确解释为什么会发生这种情况的资源。我认为它在网上某个地方,但我错过了正确的关键字来找到我要找的东西。
为了解释这种情况,假设我有以下目录树。请注意如何将三个对象导入为 config
:
.
├ config
│ └ index.js # Exports a simple object: `module.exports = { file: "config/index.js" };`
├ config.js # Exports a another object: `module.exports = { file: "config.js" };`
├ config.json # Contains a different json: `{ "file": "config.json" }`
└ module
└ index.js
现在在 module/index.js
如果我 require
其他三个文件中的任何一个明确地一切都按预期进行:
console.log(require("../config.js")); // { file: 'config.js' }
console.log(require("../config.json")); // { file: 'config.json' }
console.log(require("../config/index.js")); // { file: 'config/index.js' }
我需要解释的行为是当我 require('../config')
没有指定确切的文件时。从我的测试来看,优先级似乎是这样的:
- 首先尝试导入
config.js
- 然后尝试导入
config.json
- 如果 none 存在,请尝试导入
config/index.js
但是我找不到任何可以明确指定此行为的资源。我阅读了 this nodejs doc 但找不到有关此特定行为的规范。我在哪里可以了解有关 require
对类似模块名称应用的优先顺序的更多信息?
require()
的规则和优先级已经非常清楚 here in the nodejs doc。
开头是这样的:
require(X) from module at path Y
1. If X is a core module,
a. return the core module
b. STOP
2. If X begins with '/'
a. set Y to be the filesystem root
3. If X begins with './' or '/' or '../'
a. LOAD_AS_FILE(Y + X)
b. LOAD_AS_DIRECTORY(Y + X)
c. THROW "not found"
4. If X begins with '#'
a. LOAD_PACKAGE_IMPORTS(X, dirname(Y))
5. LOAD_PACKAGE_SELF(X, dirname(Y))
6. LOAD_NODE_MODULES(X, dirname(Y))
7. THROW "not found"
由于第 1 步或第 2 步均不适用,但第 3 步确实适用,因此它将首先尝试使用 LOAD_AS_FILE(Y + X)
的 3a。
而且,LOAD_AS_FILE
看起来像这样:
LOAD_AS_FILE(X)
1. If X is a file, load X as its file extension format. STOP
2. If X.js is a file, load X.js as JavaScript text. STOP
3. If X.json is a file, parse X.json to a JavaScript Object. STOP
4. If X.node is a file, load X.node as binary addon. STOP
从那里,您可以看到您观察到的优先级是先查找 config.js
,然后是 config.json
。
只有当这两个都失败时,它才会转到步骤 3b LOAD_AS_DIRECORY(Y+X)
,在那里它会找到 index.js
.