链接


¥Chaining

可以多次调用 register

¥It's possible to call register more than once:

// 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');

在这个例子中,注册的钩子将形成链。这些链按后进先出 (LIFO) 方式运行。如果 foo.mjsbar.mjs 都定义了 resolve 钩子,它们将像这样被调用(注意从右到左):节点的默认值 ← ./foo.mjs./bar.mjs (从 ./bar.mjs 开始,然后是 ./foo.mjs,然后是 Node.js 默认值)。这同样适用于所有其他钩子。

¥In this example, the registered hooks will form chains. These chains run last-in, first out (LIFO). If both foo.mjs and bar.mjs define a resolve hook, they will be called like so (note the right-to-left): node's default ← ./foo.mjs./bar.mjs (starting with ./bar.mjs, then ./foo.mjs, then the Node.js default). The same applies to all the other hooks.

注册的钩子也会影响 register 本身。在此示例中,bar.mjs 将通过 foo.mjs 注册的钩子进行解析和加载(因为 foo 的钩子已添加到链中)。这允许用非 JavaScript 语言编写钩子之类的事情,只要早期注册的钩子可以转换为 JavaScript。

¥The registered hooks also affect register itself. In this example, 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 within the module that defines the hooks.

registerHooks 的链接工作方式类似。如果混合使用同步和异步钩子,则同步钩子总是在异步钩子开始运行之前先运行,也就是说,在运行的最后一个同步钩子中,它的下一个钩子包括对异步钩子的调用。

¥Chaining of registerHooks work similarly. 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 { registerHooks } from 'node:module';

const hook1 = { /* implementation of hooks */ };
const hook2 = { /* implementation of hooks */ };
// hook2 run before hook1.
registerHooks(hook1);
registerHooks(hook2);// entrypoint.cjs
const { registerHooks } = require('node:module');

const hook1 = { /* implementation of hooks */ };
const hook2 = { /* implementation of hooks */ };
// hook2 run before hook1.
registerHooks(hook1);
registerHooks(hook2);