模块加载器
Node.js 有两个系统用于解析说明符和加载模块。
有 CommonJS 模块加载器:
- 它是完全同步的。
- 它负责处理
require()
调用。 - 它是可修补的。
- 它支持文件夹作为模块。
- 当解析说明符时,如果没有找到完全的匹配,则它将尝试添加扩展名(
.js
、.json
,最后是.node
),然后尝试将文件夹作为模块解析。 - 它将
.json
视为 JSON 文本文件。 .node
文件被解释为加载了process.dlopen()
的编译插件模块。- 它将所有缺少
.json
或.node
扩展名的文件视为 JavaScript 文本文件。 - 它不能用于加载 ECMAScript 模块(尽管可以从 CommonJS 模块加载 ECMASCript 模块)。 当用于加载不是 ECMAScript 模块的 JavaScript 文本文件时,则它将作为 CommonJS 模块加载。
有 ECMAScript 模块加载器:
- 它是异步的。
- 负责处理
import
语句和import()
表达式。 - 它不是可修补的,可以使用加载器钩子自定义。
- 它不支持文件夹作为模块,必须完全指定目录索引(例如
'./startup/index.js'
)。 - 它不进行扩展名搜索。 当说明符是相对或绝对的文件 URL 时,必须提供文件扩展名。
- 它可以加载 JSON 模块,但需要导入断言。
- 它只接受 JavaScript 文本文件的
.js
、.mjs
和.cjs
扩展名。 - 它可以用来加载 JavaScript CommonJS 模块。
这样的模块通过
cjs-module-lexer
来尝试识别命名的导出,如果可以通过静态分析确定的话是可用的。 导入的 CommonJS 模块将其 URL 转换为绝对路径,然后通过 CommonJS 模块加载器加载。
Node.js has two systems for resolving a specifier and loading modules.
There is the CommonJS module loader:
- It is fully synchronous.
- It is responsible for handling
require()
calls. - It is monkey patchable.
- It supports folders as modules.
- When resolving a specifier, if no exact match is found, it will try to add
extensions (
.js
,.json
, and finally.node
) and then attempt to resolve folders as modules. - It treats
.json
as JSON text files. .node
files are interpreted as compiled addon modules loaded withprocess.dlopen()
.- It treats all files that lack
.json
or.node
extensions as JavaScript text files. - It cannot be used to load ECMAScript modules (although it is possible to load ECMASCript modules from CommonJS modules). When used to load a JavaScript text file that is not an ECMAScript module, it loads it as a CommonJS module.
There is the ECMAScript module loader:
- It is asynchronous.
- It is responsible for handling
import
statements andimport()
expressions. - It is not monkey patchable, can be customized using loader hooks.
- It does not support folders as modules, directory indexes (e.g.
'./startup/index.js'
) must be fully specified. - It does no extension searching. A file extension must be provided when the specifier is a relative or absolute file URL.
- It can load JSON modules, but an import assertion is required.
- It accepts only
.js
,.mjs
, and.cjs
extensions for JavaScript text files. - It can be used to load JavaScript CommonJS modules. Such modules
are passed through the
cjs-module-lexer
to try to identify named exports, which are available if they can be determined through static analysis. Imported CommonJS modules have their URLs converted to absolute paths and are then loaded via the CommonJS module loader.