diff --git a/doc/api/esm.md b/doc/api/esm.md index 68ecad93b8ad3b..8847f300e17451 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -685,6 +685,9 @@ of Node.js applications. + +> The loaders API is being redesigned. This hook may disappear or its +> signature may change. Do not rely on the API described below. + +* `data` {any} The data from `register(loader, import.meta.url, { data })`. +* Returns: {any} The data to be returned to the caller of `register`. + +The `initialize` hook provides a way to define a custom function that runs +in the loader's thread when the loader is initialized. This hook can send +and receive data from a [`register`][] invocation, including ports and other +transferrable objects. The return value of `initialize` must be something +that can be posted as a message between threads, like the input to +[`port.postMessage`][]. + +Loader code: + +```js +// In the below example this file is referenced as +// '/path-to-my-loader.js' + +export function initialize({ number, port }) { + port.postMessage(`increment: ${number + 1}`); + return 'ok'; +} +``` + +Caller code: + +```js +import assert from 'node:assert'; +import { register } from 'node:module'; +import { MessageChannel } from 'node:worker_threads'; + +// This example showcases how a message channel can be used to +// communicate between the main (application) thread and the loader +// running on the loaders thread, by sending `port2` to the loader. +const { port1, port2 } = new MessageChannel(); + +port1.on('message', (msg) => { + assert.strictEqual(msg, 'increment: 2'); +}); + +const result = register('/path-to-my-loader.js', { + parentURL: import.meta.url, + data: { number: 1, port: port2 }, + transferList: [port2], +}); + +assert.strictEqual(result, 'ok'); +``` + #### `resolve(specifier, context, nextResolve)` -> The loaders API is being redesigned. This hook may disappear or its -> signature may change. Do not rely on the API described below. +> This hook will be removed in a future version. Use [`initialize`][] instead. +> When a loader has an `initilize` export, `globalPreload` will be ignored. > In a previous version of this API, this hook was named > `getGlobalPreloadCode`. @@ -1609,13 +1668,16 @@ for ESM specifiers is [commonjs-extension-resolution-loader][]. [`import.meta.resolve`]: #importmetaresolvespecifier-parent [`import.meta.url`]: #importmetaurl [`import`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import +[`initialize`]: #initialize [`module.createRequire()`]: module.md#modulecreaterequirefilename [`module.register()`]: module.md#moduleregister [`module.syncBuiltinESMExports()`]: module.md#modulesyncbuiltinesmexports [`package.json`]: packages.md#nodejs-packagejson-field-definitions +[`port.postMessage`]: worker_threads.md#portpostmessagevalue-transferlist [`port.ref()`]: https://nodejs.org/dist/latest-v17.x/docs/api/worker_threads.html#portref [`port.unref()`]: https://nodejs.org/dist/latest-v17.x/docs/api/worker_threads.html#portunref [`process.dlopen`]: process.md#processdlopenmodule-filename-flags +[`register`]: module.md#moduleregister [`string`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String [`util.TextDecoder`]: util.md#class-utiltextdecoder [cjs-module-lexer]: https://github.com/nodejs/cjs-module-lexer/tree/1.2.2 diff --git a/doc/api/module.md b/doc/api/module.md index 8dd5fd4fa59f6c..f98d011cc53bb5 100644 --- a/doc/api/module.md +++ b/doc/api/module.md @@ -175,6 +175,28 @@ globalPreload: http-to-https globalPreload: unpkg ``` +This function can also be used to pass data to the loader's [`initialize`][] +hook include transferrable objects like ports. + +```mjs +import { register } from 'node:module'; +import { MessageChannel } from 'node:worker_threads'; + +// This example showcases how a message channel can be used to +// communicate to the loader, by sending `port2` to the loader. +const { port1, port2 } = new MessageChannel(); + +port1.on('message', (msg) => { + console.log(msg); +}); + +register('./my-programmatic-loader.mjs', { + parentURL: import.meta.url, + data: { number: 1, port: port2 }, + transferList: [port2], +}); +``` + ### `module.syncBuiltinESMExports()`