异步 resolve(specifier, context, nextResolve)


🌐 Asynchronous resolve(specifier, context, nextResolve)

  • specifier <string>
  • context <Object>
    • conditions <string[]> 相关 package.json 的导出条件
    • importAttributes <Object> 一个对象,其键值对表示要导入模块的属性
    • parentURL <string> | <undefined> 导入此模块的模块,如果这是 Node.js 的入口点,则为未定义
  • nextResolve <Function> 链中的后续 resolve 钩子,或最后一个用户提供的 resolve 钩子之后的 Node.js 默认 resolve 钩子
    • specifier <string>
    • context <Object> | <undefined> 如果省略,将使用默认值。提供时,默认值会与提供的属性合并,但以提供的属性为优先。
  • 返回:<Object> | <Promise> 异步版本接受一个包含以下属性的对象,或者一个将解析为此类对象的 Promise
    • format <string> | <null> | <undefined> load 钩子的提示(可能会被忽略)。它可以是一个模块格式(例如 'commonjs''module'),也可以是像 'css''yaml' 这样的任意值。
    • importAttributes <Object> | <undefined> 缓存模块时要使用的导入属性(可选;如果省略,将使用输入)
    • shortCircuit <undefined> | <boolean> 一个信号,表示此钩子打算终止 resolve 钩子链。默认值: false
    • url <string> 此输入解析后的绝对 URL

异步版本的工作原理与同步版本类似,只是 nextResolve 函数返回一个 Promise,并且 resolve 钩子本身可以返回一个 Promise

🌐 The asynchronous version works similarly to the synchronous version, only that the nextResolve function returns a Promise, and the resolve hook itself can return a Promise.

警告 在异步版本中,尽管支持返回 promise 和异步函数,调用 resolve 仍可能阻塞主线程,从而影响性能。

警告 对 CommonJS 模块中的 require() 调用调用的 resolve 钩子 被异步钩子自定义时,不会接收到传递给 require() 的原始标识符。 相反,它接收到的是已经使用默认 CommonJS 解析完全解析的 URL。

警告 在由异步自定义钩子定制的 CommonJS 模块中, require.resolve()require() 将使用 "import" 导出条件而不是 "require",这可能在加载双重包时导致意外行为。

export async function resolve(specifier, context, nextResolve) {
  // When calling `defaultResolve`, the arguments can be modified. For example,
  // to change the specifier or add conditions.
  if (specifier.includes('foo')) {
    specifier = specifier.replace('foo', 'bar');
    return nextResolve(specifier, {
      ...context,
      conditions: [...context.conditions, 'another-condition'],
    });
  }

  // The hook can also skips default resolution and provide a custom URL.
  if (specifier === 'special-module') {
    return {
      url: 'file:///path/to/special-module.mjs',
      format: 'module',
      shortCircuit: true,  // This is mandatory if not calling nextResolve().
    };
  }

  // If no customization is needed, defer to the next hook in the chain which would be the
  // Node.js default resolve if this is the last user-specified loader.
  return nextResolve(specifier);
}