异步自定义钩子的链式调用


🌐 Chaining of asynchronous customization hooks

register() 的链式调用工作方式类似于 registerHooks()。如果同步和异步钩子混合使用,同步钩子总是先执行,然后才开始执行异步钩子,也就是说,在最后一个运行的同步钩子中,它的下一个钩子包括异步钩子的调用。

🌐 Chaining of register() work similarly to registerHooks(). If synchronous and asynchronous hooks are mixed, the synchronous hooks are always run first before the asynchronous hooks start running, that is, in the last synchronous hook being run, its next hook includes invocation of the asynchronous hooks.

// entrypoint.mjs
import { register } from 'node:module';

register('./foo.mjs', import.meta.url);
register('./bar.mjs', import.meta.url);
await import('./my-app.mjs');// entrypoint.cjs
const { register } = require('node:module');
const { pathToFileURL } = require('node:url');

const parentURL = pathToFileURL(__filename);
register('./foo.mjs', parentURL);
register('./bar.mjs', parentURL);
import('./my-app.mjs');

如果 foo.mjsbar.mjs 定义了一个 resolve 钩子,它们将像这样被调用 (注意从右到左,先是 ./bar.mjs,然后是 ./foo.mjs,最后是 Node.js 默认的):

🌐 If foo.mjs and bar.mjs define a resolve hook, they will be called like so (note the right-to-left, starting with ./bar.mjs, then ./foo.mjs, then the Node.js default):

Node.js 默认 ← ./foo.mjs./bar.mjs

🌐 Node.js default ← ./foo.mjs./bar.mjs

在使用异步钩子时,已注册的钩子也会影响随后的 register 调用,它负责加载钩子模块。在上面的示例中,bar.mjs 将通过 foo.mjs 注册的钩子来解析和加载(因为 foo 的钩子已被添加到链中)。这允许编写非 JavaScript 语言的钩子,只要先前注册的钩子能够转换为 JavaScript。

🌐 When using the asynchronous hooks, the registered hooks also affect subsequent register calls, which takes care of loading hook modules. In the example above, bar.mjs will be resolved and loaded via the hooks registered by foo.mjs (because foo's hooks will have already been added to the chain). This allows for things like writing hooks in non-JavaScript languages, so long as earlier registered hooks transpile into JavaScript.

register() 方法不能从运行导出异步钩子的钩子模块或其依赖的线程中调用。

🌐 The register() method cannot be called from the thread running the hook module that exports the asynchronous hooks or its dependencies.