异步 load(url, context, nextLoad)
🌐 Asynchronous load(url, context, nextLoad)
-
url<string>resolve链返回的 URL -
context<Object>conditions<string[]> 相关package.json的导出条件format<string> | <null> | <undefined>resolve钩子链可选择提供的格式。这可以是任何字符串值作为输入;输入值不需要符合下文描述的可接受返回值列表。importAttributes<Object>
-
nextLoad<Function> 链中的后续load钩子,或最后一个用户提供的load钩子之后的 Node.js 默认load钩子-
url<string> -
context<Object> | <undefined> 如果省略,将提供默认值。如果提供,将与默认值合并,并优先使用提供的属性。在默认nextLoad中,如果url指向的模块没有明确的模块类型信息,则context.format是必需的。
-
-
返回:<Promise> 异步版本接受一个包含以下属性的对象,或者一个将解析为此类对象的
Promise。format<string>shortCircuit<undefined> | <boolean> 一个信号,表示此钩子打算终止load钩子链。默认值:falsesource<string> | <ArrayBuffer> | <TypedArray> 用于评估的 Node.js 源
警告:异步
load钩子与来自 CommonJS 模块的命名空间导出不兼容。尝试将它们一起使用将导致导入结果为空对象。未来可能会解决此问题。这不适用于同步load钩子,在这种情况下可以像平常一样使用导出。
异步版本的工作方式与同步版本类似,但在使用异步 load 钩子时,省略与提供 'commonjs' 的 source 会产生非常不同的效果:
🌐 The asynchronous version works similarly to the synchronous version, though
when using the asynchronous load hook, 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。
这些注意事项不适用于同步的 load 钩子,在这种情况下,自定义 CommonJS 模块可以使用完整的 CommonJS API 集,require/require.resolve 始终会通过已注册的钩子。
🌐 These caveats do not apply to the synchronous load hook, in which case
the complete set of CommonJS APIs available to the customized CommonJS
modules, and require/require.resolve always go through the registered
hooks.
Node.js 内部的异步 load 实现,即 load 链中最后一个钩子的 next 值,当 format 为 'commonjs' 时,会为了向后兼容而返回 null 作为 source。下面是一个示例钩子,它将选择使用非默认行为:
🌐 The Node.js internal asynchronous 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';
// Asynchronous version accepted by module.register(). This fix is not needed
// for the synchronous version accepted by module.registerHooks().
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;
} 这同样不适用于同步的 load 钩子,在这种情况下,返回的 source 包含由下一个钩子加载的源代码,无论模块格式如何。
🌐 This doesn't apply to the synchronous load hook either, in which case the
source returned contains source code loaded by the next hook, regardless
of module format.