load(url, context, nextLoad)
url<string>resolve链返回的 URLcontext<Object>conditions<string[]> 相关package.json的导出条件format<string> | <null> | <undefined>resolve钩子链可选择提供的格式importAttributes<Object>
nextLoad<Function> 链中的后续load钩子,或最后一个用户提供的load钩子之后的 Node.js 默认load钩子- 返回:<Object>
format<string>shortCircuit<undefined> | <boolean> 一个信号,表示此钩子打算终止load钩子链。默认值:falsesource<string> | <ArrayBuffer> | <TypedArray> 用于评估的 Node.js 源
load 钩子提供了一种定义自定义方法的方法,用于确定 URL 应该如何被解释、获取和解析。它还负责验证导入断言。
🌐 The load hook provides a way to define a custom method of determining how a
URL should be interpreted, retrieved, and parsed. It is also in charge of
validating the import assertion.
format 的最终值必须是以下之一:
🌐 The final value of format must be one of the following:
format | 描述 | load 返回的 source 可接受类型 |
|---|---|---|
'builtin' | 加载 Node.js 内置模块 | 不适用 |
'commonjs' | 加载 Node.js CommonJS 模块 | { string, ArrayBuffer, TypedArray, null, undefined } |
'json' | 加载 JSON 文件 | { string, ArrayBuffer, TypedArray } |
'module' | 加载 ES 模块 | { string, ArrayBuffer, TypedArray } |
'wasm' | 加载 WebAssembly 模块 | { ArrayBuffer, TypedArray } |
source 的值会被忽略,因为对于 'builtin' 类型,目前无法替换 Node.js 内置(核心)模块的值。
🌐 The value of source is ignored for type 'builtin' because currently it is
not possible to replace the value of a Node.js builtin (core) module.
省略与提供 'commonjs' 的 source 会产生非常不同的效果:
🌐 Omitting vs providing a source for 'commonjs' has very different effects:
- 当提供
source时,该模块中的所有require调用将由 ESM 加载器处理,并使用已注册的resolve和load钩子;该模块中的所有require.resolve调用将由 ESM 加载器处理,并使用已注册的resolve钩子;只有部分 CommonJS API 可用(例如没有require.extensions、没有require.cache、没有require.resolve.paths),对 CommonJS 模块加载器的猴子补丁将不生效。 - 如果
source是未定义或null,它将由 CommonJS 模块加载器处理,并且require/require.resolve调用不会经过注册的钩子。对于 null 值的source,这种行为是暂时的——将来将不再支持 null 值的source。
当使用 --experimental-default-type=commonjs 运行 node 时,Node.js 内部的 load 实现(即 load 链中最后一个 hook 的 next 值)在 format 为 'commonjs' 时会返回 null 作为 source,以保持向后兼容。下面是一个示例 hook,它会选择使用非默认行为:
🌐 When node is run with --experimental-default-type=commonjs, the Node.js
internal load implementation, which is the value of next for the
last hook in the load chain, returns null for source when format is
'commonjs' for backward compatibility. Here is an example hook that would
opt-in to using the non-default behavior:
import { readFile } from 'node:fs/promises';
export async function load(url, context, nextLoad) {
const result = await nextLoad(url, context);
if (result.format === 'commonjs') {
result.source ??= await readFile(new URL(result.responseURL ?? url));
}
return result;
} 警告:ESM 的
load钩子与来自 CommonJS 模块的命名导出不兼容。尝试将它们一起使用将导致从导入中得到一个空对象。未来可能会解决这个问题。
这些类型都对应于 ECMAScript 中定义的类。
- 特定的
ArrayBuffer对象是一个SharedArrayBuffer。 - 特定的
TypedArray对象是一个Uint8Array。
如果基于文本的格式(即 'json'、'module')的源值不是字符串,它将使用 util.TextDecoder 转换为字符串。
🌐 If the source value of a text-based format (i.e., 'json', 'module')
is not a string, it is converted to a string using util.TextDecoder.
load 钩子提供了一种方式来定义用于获取已解析 URL 源代码的自定义方法。这允许加载器在潜在情况下避免从磁盘读取文件。它也可以用于将无法识别的格式映射为受支持的格式,例如将 yaml 映射为 module。
🌐 The load hook provides a way to define a custom method for retrieving the
source code of a resolved URL. This would allow a loader to potentially avoid
reading files from disk. It could also be used to map an unrecognized format to
a supported one, for example yaml to module.
export async function load(url, context, nextLoad) {
const { format } = context;
if (Math.random() > 0.5) { // Some condition
/*
For some or all URLs, do some custom logic for retrieving the source.
Always return an object of the form {
format: <string>,
source: <string|buffer>,
}.
*/
return {
format,
shortCircuit: true,
source: '...',
};
}
// Defer to the next hook in the chain.
return nextLoad(url);
} 在更高级的场景中,这也可以用来将不受支持的源转换为受支持的源(见下方示例)。
🌐 In a more advanced scenario, this can also be used to transform an unsupported source to a supported one (see Examples below).