启用


【Enabling】

模块解析和加载可以通过注册一个导出一组钩子的文件来自定义。这可以通过使用 node:module 中的 register 方法来完成,你可以在使用 --import 标志运行应用代码之前执行该方法:

【Module resolution and loading can be customized by registering a file which exports a set of hooks. This can be done using the register method from node:module, which you can run before your application code by using the --import flag:】

node --import ./register-hooks.js ./my-app.js 
// register-hooks.js
import { register } from 'node:module';

register('./hooks.mjs', import.meta.url);// register-hooks.js
const { register } = require('node:module');
const { pathToFileURL } = require('node:url');

register('./hooks.mjs', pathToFileURL(__filename));

传递给 --import 的文件也可以是依赖的导出文件:

【The file passed to --import can also be an export from a dependency:】

node --import some-package/register ./my-app.js 

some-package 包含一个 "exports" 字段,用于定义 /register 导出,以映射到调用 register() 的文件,例如以下 register-hooks.js 示例。

【Where some-package has an "exports" field defining the /register export to map to a file that calls register(), like the following register-hooks.js example.】

使用 --import 可以确保在导入任何应用文件(包括应用的入口点)之前注册钩子。或者,可以从入口点调用 register,但对于任何在钩子注册后应运行的代码,必须使用动态 import()

【Using --import ensures that the hooks are registered before any application files are imported, including the entry point of the application. Alternatively, register can be called from the entry point, but dynamic import() must be used for any code that should be run after the hooks are registered:】

import { register } from 'node:module';

register('http-to-https', import.meta.url);

// Because this is a dynamic `import()`, the `http-to-https` hooks will run
// to handle `./my-app.js` and any other files it imports or requires.
await import('./my-app.js');const { register } = require('node:module');
const { pathToFileURL } = require('node:url');

register('http-to-https', pathToFileURL(__filename));

// Because this is a dynamic `import()`, the `http-to-https` hooks will run
// to handle `./my-app.js` and any other files it imports or requires.
import('./my-app.js');

在这个例子中,我们正在注册 http-to-https 钩子,但它们只会对随后导入的模块可用——在本例中是 my-app.js 以及它通过 import(可选地通过 require)引用的任何内容。如果 import('./my-app.js') 替换为静态的 import './my-app.js',那么应用将在 http-to-https 钩子注册之前就已 加载。这是由于 ES 模块规范,静态导入会先从树的叶节点开始求值,然后回到主干。在 my-app.js 中可能存在静态导入,这些导入在 my-app.js 动态导入之前不会被求值。

【In this example, we are registering the http-to-https hooks, but they will only be available for subsequently imported modules—in this case, my-app.js and anything it references via import (and optionally require). If the import('./my-app.js') had instead been a static import './my-app.js', the app would have already been loaded before the http-to-https hooks were registered. This due to the ES modules specification, where static imports are evaluated from the leaves of the tree first, then back to the trunk. There can be static imports within my-app.js, which will not be evaluated until my-app.js is dynamically imported.】

my-app.js 也可以是 CommonJS 模块。自定义钩子会针对它通过 import(可选的 require)引用的任何模块执行。

最后,如果你只是想在应用运行前注册钩子,并且不想为此创建一个单独的文件,你可以将一个 data: URL 传递给 --import

【Finally, if all you want to do is register hooks before your app runs and you don't want to create a separate file for that purpose, you can pass a data: URL to --import:】

node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register("http-to-https", pathToFileURL("./"));' ./my-app.js