启用
¥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
)引用的任何模块运行。
¥my-app.js
can also be CommonJS. Customization hooks will run for any
modules that it references via import
(and optionally 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