load(url, context, nextLoad)


稳定性: 1.2 - 发布候选版

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 加载器处理,并使用已注册的 resolveload 钩子;该模块中的所有 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 中定义的类。

如果基于文本的格式(即 '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).