11cb0ef41Sopenharmony_ci# Modules: `node:module` API 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ci<!--introduced_in=v12.20.0--> 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci<!-- YAML 61cb0ef41Sopenharmony_ciadded: v0.3.7 71cb0ef41Sopenharmony_ci--> 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ci## The `Module` object 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ci* {Object} 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ciProvides general utility methods when interacting with instances of 141cb0ef41Sopenharmony_ci`Module`, the [`module`][] variable often seen in [CommonJS][] modules. Accessed 151cb0ef41Sopenharmony_civia `import 'node:module'` or `require('node:module')`. 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ci### `module.builtinModules` 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ci<!-- YAML 201cb0ef41Sopenharmony_ciadded: 211cb0ef41Sopenharmony_ci - v9.3.0 221cb0ef41Sopenharmony_ci - v8.10.0 231cb0ef41Sopenharmony_ci - v6.13.0 241cb0ef41Sopenharmony_ci--> 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci* {string\[]} 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ciA list of the names of all modules provided by Node.js. Can be used to verify 291cb0ef41Sopenharmony_ciif a module is maintained by a third party or not. 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ci`module` in this context isn't the same object that's provided 321cb0ef41Sopenharmony_ciby the [module wrapper][]. To access it, require the `Module` module: 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci```mjs 351cb0ef41Sopenharmony_ci// module.mjs 361cb0ef41Sopenharmony_ci// In an ECMAScript module 371cb0ef41Sopenharmony_ciimport { builtinModules as builtin } from 'node:module'; 381cb0ef41Sopenharmony_ci``` 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci```cjs 411cb0ef41Sopenharmony_ci// module.cjs 421cb0ef41Sopenharmony_ci// In a CommonJS module 431cb0ef41Sopenharmony_ciconst builtin = require('node:module').builtinModules; 441cb0ef41Sopenharmony_ci``` 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci### `module.createRequire(filename)` 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ci<!-- YAML 491cb0ef41Sopenharmony_ciadded: v12.2.0 501cb0ef41Sopenharmony_ci--> 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci* `filename` {string|URL} Filename to be used to construct the require 531cb0ef41Sopenharmony_ci function. Must be a file URL object, file URL string, or absolute path 541cb0ef41Sopenharmony_ci string. 551cb0ef41Sopenharmony_ci* Returns: {require} Require function 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci```mjs 581cb0ef41Sopenharmony_ciimport { createRequire } from 'node:module'; 591cb0ef41Sopenharmony_ciconst require = createRequire(import.meta.url); 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci// sibling-module.js is a CommonJS module. 621cb0ef41Sopenharmony_ciconst siblingModule = require('./sibling-module'); 631cb0ef41Sopenharmony_ci``` 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci### `module.isBuiltin(moduleName)` 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ci<!-- YAML 681cb0ef41Sopenharmony_ciadded: v18.6.0 691cb0ef41Sopenharmony_ci--> 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci* `moduleName` {string} name of the module 721cb0ef41Sopenharmony_ci* Returns: {boolean} returns true if the module is builtin else returns false 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci```mjs 751cb0ef41Sopenharmony_ciimport { isBuiltin } from 'node:module'; 761cb0ef41Sopenharmony_ciisBuiltin('node:fs'); // true 771cb0ef41Sopenharmony_ciisBuiltin('fs'); // true 781cb0ef41Sopenharmony_ciisBuiltin('wss'); // false 791cb0ef41Sopenharmony_ci``` 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci### `module.register(specifier[, parentURL][, options])` 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci<!-- YAML 841cb0ef41Sopenharmony_ciadded: v18.19.0 851cb0ef41Sopenharmony_cichanges: 861cb0ef41Sopenharmony_ci - version: v18.19.0 871cb0ef41Sopenharmony_ci pr-url: https://github.com/nodejs/node/pull/49655 881cb0ef41Sopenharmony_ci description: Add support for WHATWG URL instances. 891cb0ef41Sopenharmony_ci--> 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci> Stability: 1.1 - Active development 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci* `specifier` {string|URL} Customization hooks to be registered; this should be 941cb0ef41Sopenharmony_ci the same string that would be passed to `import()`, except that if it is 951cb0ef41Sopenharmony_ci relative, it is resolved relative to `parentURL`. 961cb0ef41Sopenharmony_ci* `parentURL` {string|URL} If you want to resolve `specifier` relative to a base 971cb0ef41Sopenharmony_ci URL, such as `import.meta.url`, you can pass that URL here. **Default:** 981cb0ef41Sopenharmony_ci `'data:'` 991cb0ef41Sopenharmony_ci* `options` {Object} 1001cb0ef41Sopenharmony_ci * `data` {any} Any arbitrary, cloneable JavaScript value to pass into the 1011cb0ef41Sopenharmony_ci [`initialize`][] hook. 1021cb0ef41Sopenharmony_ci * `transferList` {Object\[]} [transferrable objects][] to be passed into the 1031cb0ef41Sopenharmony_ci `initialize` hook. 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ciRegister a module that exports [hooks][] that customize Node.js module 1061cb0ef41Sopenharmony_ciresolution and loading behavior. See [Customization hooks][]. 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci### `module.syncBuiltinESMExports()` 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci<!-- YAML 1111cb0ef41Sopenharmony_ciadded: v12.12.0 1121cb0ef41Sopenharmony_ci--> 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_ciThe `module.syncBuiltinESMExports()` method updates all the live bindings for 1151cb0ef41Sopenharmony_cibuiltin [ES Modules][] to match the properties of the [CommonJS][] exports. It 1161cb0ef41Sopenharmony_cidoes not add or remove exported names from the [ES Modules][]. 1171cb0ef41Sopenharmony_ci 1181cb0ef41Sopenharmony_ci```js 1191cb0ef41Sopenharmony_ciconst fs = require('node:fs'); 1201cb0ef41Sopenharmony_ciconst assert = require('node:assert'); 1211cb0ef41Sopenharmony_ciconst { syncBuiltinESMExports } = require('node:module'); 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_cifs.readFile = newAPI; 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_cidelete fs.readFileSync; 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_cifunction newAPI() { 1281cb0ef41Sopenharmony_ci // ... 1291cb0ef41Sopenharmony_ci} 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_cifs.newAPI = newAPI; 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_cisyncBuiltinESMExports(); 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_ciimport('node:fs').then((esmFS) => { 1361cb0ef41Sopenharmony_ci // It syncs the existing readFile property with the new value 1371cb0ef41Sopenharmony_ci assert.strictEqual(esmFS.readFile, newAPI); 1381cb0ef41Sopenharmony_ci // readFileSync has been deleted from the required fs 1391cb0ef41Sopenharmony_ci assert.strictEqual('readFileSync' in fs, false); 1401cb0ef41Sopenharmony_ci // syncBuiltinESMExports() does not remove readFileSync from esmFS 1411cb0ef41Sopenharmony_ci assert.strictEqual('readFileSync' in esmFS, true); 1421cb0ef41Sopenharmony_ci // syncBuiltinESMExports() does not add names 1431cb0ef41Sopenharmony_ci assert.strictEqual(esmFS.newAPI, undefined); 1441cb0ef41Sopenharmony_ci}); 1451cb0ef41Sopenharmony_ci``` 1461cb0ef41Sopenharmony_ci 1471cb0ef41Sopenharmony_ci<i id="module_customization_hooks"></i> 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ci## Customization Hooks 1501cb0ef41Sopenharmony_ci 1511cb0ef41Sopenharmony_ci<!-- YAML 1521cb0ef41Sopenharmony_ciadded: v8.8.0 1531cb0ef41Sopenharmony_cichanges: 1541cb0ef41Sopenharmony_ci - version: v18.19.0 1551cb0ef41Sopenharmony_ci pr-url: https://github.com/nodejs/node/pull/48842 1561cb0ef41Sopenharmony_ci description: Added `initialize` hook to replace `globalPreload`. 1571cb0ef41Sopenharmony_ci - version: 1581cb0ef41Sopenharmony_ci - v18.6.0 1591cb0ef41Sopenharmony_ci - v16.17.0 1601cb0ef41Sopenharmony_ci pr-url: https://github.com/nodejs/node/pull/42623 1611cb0ef41Sopenharmony_ci description: Add support for chaining loaders. 1621cb0ef41Sopenharmony_ci - version: v16.12.0 1631cb0ef41Sopenharmony_ci pr-url: https://github.com/nodejs/node/pull/37468 1641cb0ef41Sopenharmony_ci description: Removed `getFormat`, `getSource`, `transformSource`, and 1651cb0ef41Sopenharmony_ci `globalPreload`; added `load` hook and `getGlobalPreload` hook. 1661cb0ef41Sopenharmony_ci--> 1671cb0ef41Sopenharmony_ci 1681cb0ef41Sopenharmony_ci> Stability: 1.1 - Active development 1691cb0ef41Sopenharmony_ci 1701cb0ef41Sopenharmony_ci<!-- type=misc --> 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_ci<i id="enabling_module_customization_hooks"></i> 1731cb0ef41Sopenharmony_ci 1741cb0ef41Sopenharmony_ci### Enabling 1751cb0ef41Sopenharmony_ci 1761cb0ef41Sopenharmony_ciModule resolution and loading can be customized by registering a file which 1771cb0ef41Sopenharmony_ciexports a set of hooks. This can be done using the [`register`][] method 1781cb0ef41Sopenharmony_cifrom `node:module`, which you can run before your application code by 1791cb0ef41Sopenharmony_ciusing the `--import` flag: 1801cb0ef41Sopenharmony_ci 1811cb0ef41Sopenharmony_ci```bash 1821cb0ef41Sopenharmony_cinode --import ./register-hooks.js ./my-app.js 1831cb0ef41Sopenharmony_ci``` 1841cb0ef41Sopenharmony_ci 1851cb0ef41Sopenharmony_ci```mjs 1861cb0ef41Sopenharmony_ci// register-hooks.js 1871cb0ef41Sopenharmony_ciimport { register } from 'node:module'; 1881cb0ef41Sopenharmony_ci 1891cb0ef41Sopenharmony_ciregister('./hooks.mjs', import.meta.url); 1901cb0ef41Sopenharmony_ci``` 1911cb0ef41Sopenharmony_ci 1921cb0ef41Sopenharmony_ci```cjs 1931cb0ef41Sopenharmony_ci// register-hooks.js 1941cb0ef41Sopenharmony_ciconst { register } = require('node:module'); 1951cb0ef41Sopenharmony_ciconst { pathToFileURL } = require('node:url'); 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ciregister('./hooks.mjs', pathToFileURL(__filename)); 1981cb0ef41Sopenharmony_ci``` 1991cb0ef41Sopenharmony_ci 2001cb0ef41Sopenharmony_ciThe file passed to `--import` can also be an export from a dependency: 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_ci```bash 2031cb0ef41Sopenharmony_cinode --import some-package/register ./my-app.js 2041cb0ef41Sopenharmony_ci``` 2051cb0ef41Sopenharmony_ci 2061cb0ef41Sopenharmony_ciWhere `some-package` has an [`"exports"`][] field defining the `/register` 2071cb0ef41Sopenharmony_ciexport to map to a file that calls `register()`, like the following `register-hooks.js` 2081cb0ef41Sopenharmony_ciexample. 2091cb0ef41Sopenharmony_ci 2101cb0ef41Sopenharmony_ciUsing `--import` ensures that the hooks are registered before any application 2111cb0ef41Sopenharmony_cifiles are imported, including the entry point of the application. Alternatively, 2121cb0ef41Sopenharmony_ci`register` can be called from the entry point, but dynamic `import()` must be 2131cb0ef41Sopenharmony_ciused for any code that should be run after the hooks are registered: 2141cb0ef41Sopenharmony_ci 2151cb0ef41Sopenharmony_ci```mjs 2161cb0ef41Sopenharmony_ciimport { register } from 'node:module'; 2171cb0ef41Sopenharmony_ci 2181cb0ef41Sopenharmony_ciregister('http-to-https', import.meta.url); 2191cb0ef41Sopenharmony_ci 2201cb0ef41Sopenharmony_ci// Because this is a dynamic `import()`, the `http-to-https` hooks will run 2211cb0ef41Sopenharmony_ci// to handle `./my-app.js` and any other files it imports or requires. 2221cb0ef41Sopenharmony_ciawait import('./my-app.js'); 2231cb0ef41Sopenharmony_ci``` 2241cb0ef41Sopenharmony_ci 2251cb0ef41Sopenharmony_ci```cjs 2261cb0ef41Sopenharmony_ciconst { register } = require('node:module'); 2271cb0ef41Sopenharmony_ciconst { pathToFileURL } = require('node:url'); 2281cb0ef41Sopenharmony_ci 2291cb0ef41Sopenharmony_ciregister('http-to-https', pathToFileURL(__filename)); 2301cb0ef41Sopenharmony_ci 2311cb0ef41Sopenharmony_ci// Because this is a dynamic `import()`, the `http-to-https` hooks will run 2321cb0ef41Sopenharmony_ci// to handle `./my-app.js` and any other files it imports or requires. 2331cb0ef41Sopenharmony_ciimport('./my-app.js'); 2341cb0ef41Sopenharmony_ci``` 2351cb0ef41Sopenharmony_ci 2361cb0ef41Sopenharmony_ciIn this example, we are registering the `http-to-https` hooks, but they will 2371cb0ef41Sopenharmony_cionly be available for subsequently imported modules—in this case, `my-app.js` 2381cb0ef41Sopenharmony_ciand anything it references via `import` (and optionally `require`). If the 2391cb0ef41Sopenharmony_ci`import('./my-app.js')` had instead been a static `import './my-app.js'`, the 2401cb0ef41Sopenharmony_ciapp would have _already_ been loaded **before** the `http-to-https` hooks were 2411cb0ef41Sopenharmony_ciregistered. This due to the ES modules specification, where static imports are 2421cb0ef41Sopenharmony_cievaluated from the leaves of the tree first, then back to the trunk. There can 2431cb0ef41Sopenharmony_cibe static imports _within_ `my-app.js`, which will not be evaluated until 2441cb0ef41Sopenharmony_ci`my-app.js` is dynamically imported. 2451cb0ef41Sopenharmony_ci 2461cb0ef41Sopenharmony_ci`my-app.js` can also be CommonJS. Customization hooks will run for any 2471cb0ef41Sopenharmony_cimodules that it references via `import` (and optionally `require`). 2481cb0ef41Sopenharmony_ci 2491cb0ef41Sopenharmony_ciFinally, if all you want to do is register hooks before your app runs and you 2501cb0ef41Sopenharmony_cidon't want to create a separate file for that purpose, you can pass a `data:` 2511cb0ef41Sopenharmony_ciURL to `--import`: 2521cb0ef41Sopenharmony_ci 2531cb0ef41Sopenharmony_ci```bash 2541cb0ef41Sopenharmony_cinode --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register("http-to-https", pathToFileURL("./"));' ./my-app.js 2551cb0ef41Sopenharmony_ci``` 2561cb0ef41Sopenharmony_ci 2571cb0ef41Sopenharmony_ci### Chaining 2581cb0ef41Sopenharmony_ci 2591cb0ef41Sopenharmony_ciIt's possible to call `register` more than once: 2601cb0ef41Sopenharmony_ci 2611cb0ef41Sopenharmony_ci```mjs 2621cb0ef41Sopenharmony_ci// entrypoint.mjs 2631cb0ef41Sopenharmony_ciimport { register } from 'node:module'; 2641cb0ef41Sopenharmony_ci 2651cb0ef41Sopenharmony_ciregister('./first.mjs', import.meta.url); 2661cb0ef41Sopenharmony_ciregister('./second.mjs', import.meta.url); 2671cb0ef41Sopenharmony_ciawait import('./my-app.mjs'); 2681cb0ef41Sopenharmony_ci``` 2691cb0ef41Sopenharmony_ci 2701cb0ef41Sopenharmony_ci```cjs 2711cb0ef41Sopenharmony_ci// entrypoint.cjs 2721cb0ef41Sopenharmony_ciconst { register } = require('node:module'); 2731cb0ef41Sopenharmony_ciconst { pathToFileURL } = require('node:url'); 2741cb0ef41Sopenharmony_ci 2751cb0ef41Sopenharmony_ciconst parentURL = pathToFileURL(__filename); 2761cb0ef41Sopenharmony_ciregister('./first.mjs', parentURL); 2771cb0ef41Sopenharmony_ciregister('./second.mjs', parentURL); 2781cb0ef41Sopenharmony_ciimport('./my-app.mjs'); 2791cb0ef41Sopenharmony_ci``` 2801cb0ef41Sopenharmony_ci 2811cb0ef41Sopenharmony_ciIn this example, the registered hooks will form chains. If both `first.mjs` and 2821cb0ef41Sopenharmony_ci`second.mjs` define a `resolve` hook, both will be called, in the order they 2831cb0ef41Sopenharmony_ciwere registered. The same applies to all the other hooks. 2841cb0ef41Sopenharmony_ci 2851cb0ef41Sopenharmony_ciThe registered hooks also affect `register` itself. In this example, 2861cb0ef41Sopenharmony_ci`second.mjs` will be resolved and loaded per the hooks registered by 2871cb0ef41Sopenharmony_ci`first.mjs`. This allows for things like writing hooks in non-JavaScript 2881cb0ef41Sopenharmony_cilanguages, so long as an earlier registered loader is one that transpiles into 2891cb0ef41Sopenharmony_ciJavaScript. 2901cb0ef41Sopenharmony_ci 2911cb0ef41Sopenharmony_ciThe `register` method cannot be called from within the module that defines the 2921cb0ef41Sopenharmony_cihooks. 2931cb0ef41Sopenharmony_ci 2941cb0ef41Sopenharmony_ci### Communication with module customization hooks 2951cb0ef41Sopenharmony_ci 2961cb0ef41Sopenharmony_ciModule customization hooks run on a dedicated thread, separate from the main 2971cb0ef41Sopenharmony_cithread that runs application code. This means mutating global variables won't 2981cb0ef41Sopenharmony_ciaffect the other thread(s), and message channels must be used to communicate 2991cb0ef41Sopenharmony_cibetween the threads. 3001cb0ef41Sopenharmony_ci 3011cb0ef41Sopenharmony_ciThe `register` method can be used to pass data to an [`initialize`][] hook. The 3021cb0ef41Sopenharmony_cidata passed to the hook may include transferrable objects like ports. 3031cb0ef41Sopenharmony_ci 3041cb0ef41Sopenharmony_ci```mjs 3051cb0ef41Sopenharmony_ciimport { register } from 'node:module'; 3061cb0ef41Sopenharmony_ciimport { MessageChannel } from 'node:worker_threads'; 3071cb0ef41Sopenharmony_ci 3081cb0ef41Sopenharmony_ci// This example demonstrates how a message channel can be used to 3091cb0ef41Sopenharmony_ci// communicate with the hooks, by sending `port2` to the hooks. 3101cb0ef41Sopenharmony_ciconst { port1, port2 } = new MessageChannel(); 3111cb0ef41Sopenharmony_ci 3121cb0ef41Sopenharmony_ciport1.on('message', (msg) => { 3131cb0ef41Sopenharmony_ci console.log(msg); 3141cb0ef41Sopenharmony_ci}); 3151cb0ef41Sopenharmony_ci 3161cb0ef41Sopenharmony_ciregister('./my-hooks.mjs', { 3171cb0ef41Sopenharmony_ci parentURL: import.meta.url, 3181cb0ef41Sopenharmony_ci data: { number: 1, port: port2 }, 3191cb0ef41Sopenharmony_ci transferList: [port2], 3201cb0ef41Sopenharmony_ci}); 3211cb0ef41Sopenharmony_ci``` 3221cb0ef41Sopenharmony_ci 3231cb0ef41Sopenharmony_ci```cjs 3241cb0ef41Sopenharmony_ciconst { register } = require('node:module'); 3251cb0ef41Sopenharmony_ciconst { pathToFileURL } = require('node:url'); 3261cb0ef41Sopenharmony_ciconst { MessageChannel } = require('node:worker_threads'); 3271cb0ef41Sopenharmony_ci 3281cb0ef41Sopenharmony_ci// This example showcases how a message channel can be used to 3291cb0ef41Sopenharmony_ci// communicate with the hooks, by sending `port2` to the hooks. 3301cb0ef41Sopenharmony_ciconst { port1, port2 } = new MessageChannel(); 3311cb0ef41Sopenharmony_ci 3321cb0ef41Sopenharmony_ciport1.on('message', (msg) => { 3331cb0ef41Sopenharmony_ci console.log(msg); 3341cb0ef41Sopenharmony_ci}); 3351cb0ef41Sopenharmony_ci 3361cb0ef41Sopenharmony_ciregister('./my-hooks.mjs', { 3371cb0ef41Sopenharmony_ci parentURL: pathToFileURL(__filename), 3381cb0ef41Sopenharmony_ci data: { number: 1, port: port2 }, 3391cb0ef41Sopenharmony_ci transferList: [port2], 3401cb0ef41Sopenharmony_ci}); 3411cb0ef41Sopenharmony_ci``` 3421cb0ef41Sopenharmony_ci 3431cb0ef41Sopenharmony_ci### Hooks 3441cb0ef41Sopenharmony_ci 3451cb0ef41Sopenharmony_ciThe [`register`][] method can be used to register a module that exports a set of 3461cb0ef41Sopenharmony_cihooks. The hooks are functions that are called by Node.js to customize the 3471cb0ef41Sopenharmony_cimodule resolution and loading process. The exported functions must have specific 3481cb0ef41Sopenharmony_cinames and signatures, and they must be exported as named exports. 3491cb0ef41Sopenharmony_ci 3501cb0ef41Sopenharmony_ci```mjs 3511cb0ef41Sopenharmony_ciexport async function initialize({ number, port }) { 3521cb0ef41Sopenharmony_ci // Receives data from `register`. 3531cb0ef41Sopenharmony_ci} 3541cb0ef41Sopenharmony_ci 3551cb0ef41Sopenharmony_ciexport async function resolve(specifier, context, nextResolve) { 3561cb0ef41Sopenharmony_ci // Take an `import` or `require` specifier and resolve it to a URL. 3571cb0ef41Sopenharmony_ci} 3581cb0ef41Sopenharmony_ci 3591cb0ef41Sopenharmony_ciexport async function load(url, context, nextLoad) { 3601cb0ef41Sopenharmony_ci // Take a resolved URL and return the source code to be evaluated. 3611cb0ef41Sopenharmony_ci} 3621cb0ef41Sopenharmony_ci``` 3631cb0ef41Sopenharmony_ci 3641cb0ef41Sopenharmony_ciHooks are part of a chain, even if that chain consists of only one custom 3651cb0ef41Sopenharmony_ci(user-provided) hook and the default hook, which is always present. Hook 3661cb0ef41Sopenharmony_cifunctions nest: each one must always return a plain object, and chaining happens 3671cb0ef41Sopenharmony_cias a result of each function calling `next<hookName>()`, which is a reference to 3681cb0ef41Sopenharmony_cithe subsequent loader's hook. 3691cb0ef41Sopenharmony_ci 3701cb0ef41Sopenharmony_ciA hook that returns a value lacking a required property triggers an exception. A 3711cb0ef41Sopenharmony_cihook that returns without calling `next<hookName>()` _and_ without returning 3721cb0ef41Sopenharmony_ci`shortCircuit: true` also triggers an exception. These errors are to help 3731cb0ef41Sopenharmony_ciprevent unintentional breaks in the chain. Return `shortCircuit: true` from a 3741cb0ef41Sopenharmony_cihook to signal that the chain is intentionally ending at your hook. 3751cb0ef41Sopenharmony_ci 3761cb0ef41Sopenharmony_ciHooks are run in a separate thread, isolated from the main thread where 3771cb0ef41Sopenharmony_ciapplication code runs. That means it is a different [realm][]. The hooks thread 3781cb0ef41Sopenharmony_cimay be terminated by the main thread at any time, so do not depend on 3791cb0ef41Sopenharmony_ciasynchronous operations (like `console.log`) to complete. 3801cb0ef41Sopenharmony_ci 3811cb0ef41Sopenharmony_ci#### `initialize()` 3821cb0ef41Sopenharmony_ci 3831cb0ef41Sopenharmony_ci<!-- YAML 3841cb0ef41Sopenharmony_ciadded: v18.19.0 3851cb0ef41Sopenharmony_ci--> 3861cb0ef41Sopenharmony_ci 3871cb0ef41Sopenharmony_ci> Stability: 1.1 - Active development 3881cb0ef41Sopenharmony_ci 3891cb0ef41Sopenharmony_ci* `data` {any} The data from `register(loader, import.meta.url, { data })`. 3901cb0ef41Sopenharmony_ci 3911cb0ef41Sopenharmony_ciThe `initialize` hook provides a way to define a custom function that runs in 3921cb0ef41Sopenharmony_cithe hooks thread when the hooks module is initialized. Initialization happens 3931cb0ef41Sopenharmony_ciwhen the hooks module is registered via [`register`][]. 3941cb0ef41Sopenharmony_ci 3951cb0ef41Sopenharmony_ciThis hook can receive data from a [`register`][] invocation, including 3961cb0ef41Sopenharmony_ciports and other transferrable objects. The return value of `initialize` can be a 3971cb0ef41Sopenharmony_ci{Promise}, in which case it will be awaited before the main application thread 3981cb0ef41Sopenharmony_ciexecution resumes. 3991cb0ef41Sopenharmony_ci 4001cb0ef41Sopenharmony_ciModule customization code: 4011cb0ef41Sopenharmony_ci 4021cb0ef41Sopenharmony_ci```mjs 4031cb0ef41Sopenharmony_ci// path-to-my-hooks.js 4041cb0ef41Sopenharmony_ci 4051cb0ef41Sopenharmony_ciexport async function initialize({ number, port }) { 4061cb0ef41Sopenharmony_ci port.postMessage(`increment: ${number + 1}`); 4071cb0ef41Sopenharmony_ci} 4081cb0ef41Sopenharmony_ci``` 4091cb0ef41Sopenharmony_ci 4101cb0ef41Sopenharmony_ciCaller code: 4111cb0ef41Sopenharmony_ci 4121cb0ef41Sopenharmony_ci```mjs 4131cb0ef41Sopenharmony_ciimport assert from 'node:assert'; 4141cb0ef41Sopenharmony_ciimport { register } from 'node:module'; 4151cb0ef41Sopenharmony_ciimport { MessageChannel } from 'node:worker_threads'; 4161cb0ef41Sopenharmony_ci 4171cb0ef41Sopenharmony_ci// This example showcases how a message channel can be used to communicate 4181cb0ef41Sopenharmony_ci// between the main (application) thread and the hooks running on the hooks 4191cb0ef41Sopenharmony_ci// thread, by sending `port2` to the `initialize` hook. 4201cb0ef41Sopenharmony_ciconst { port1, port2 } = new MessageChannel(); 4211cb0ef41Sopenharmony_ci 4221cb0ef41Sopenharmony_ciport1.on('message', (msg) => { 4231cb0ef41Sopenharmony_ci assert.strictEqual(msg, 'increment: 2'); 4241cb0ef41Sopenharmony_ci}); 4251cb0ef41Sopenharmony_ci 4261cb0ef41Sopenharmony_ciregister('./path-to-my-hooks.js', { 4271cb0ef41Sopenharmony_ci parentURL: import.meta.url, 4281cb0ef41Sopenharmony_ci data: { number: 1, port: port2 }, 4291cb0ef41Sopenharmony_ci transferList: [port2], 4301cb0ef41Sopenharmony_ci}); 4311cb0ef41Sopenharmony_ci``` 4321cb0ef41Sopenharmony_ci 4331cb0ef41Sopenharmony_ci```cjs 4341cb0ef41Sopenharmony_ciconst assert = require('node:assert'); 4351cb0ef41Sopenharmony_ciconst { register } = require('node:module'); 4361cb0ef41Sopenharmony_ciconst { pathToFileURL } = require('node:url'); 4371cb0ef41Sopenharmony_ciconst { MessageChannel } = require('node:worker_threads'); 4381cb0ef41Sopenharmony_ci 4391cb0ef41Sopenharmony_ci// This example showcases how a message channel can be used to communicate 4401cb0ef41Sopenharmony_ci// between the main (application) thread and the hooks running on the hooks 4411cb0ef41Sopenharmony_ci// thread, by sending `port2` to the `initialize` hook. 4421cb0ef41Sopenharmony_ciconst { port1, port2 } = new MessageChannel(); 4431cb0ef41Sopenharmony_ci 4441cb0ef41Sopenharmony_ciport1.on('message', (msg) => { 4451cb0ef41Sopenharmony_ci assert.strictEqual(msg, 'increment: 2'); 4461cb0ef41Sopenharmony_ci}); 4471cb0ef41Sopenharmony_ci 4481cb0ef41Sopenharmony_ciregister('./path-to-my-hooks.js', { 4491cb0ef41Sopenharmony_ci parentURL: pathToFileURL(__filename), 4501cb0ef41Sopenharmony_ci data: { number: 1, port: port2 }, 4511cb0ef41Sopenharmony_ci transferList: [port2], 4521cb0ef41Sopenharmony_ci}); 4531cb0ef41Sopenharmony_ci``` 4541cb0ef41Sopenharmony_ci 4551cb0ef41Sopenharmony_ci#### `resolve(specifier, context, nextResolve)` 4561cb0ef41Sopenharmony_ci 4571cb0ef41Sopenharmony_ci<!-- YAML 4581cb0ef41Sopenharmony_cichanges: 4591cb0ef41Sopenharmony_ci - version: v18.19.0 4601cb0ef41Sopenharmony_ci pr-url: https://github.com/nodejs/node/pull/50140 4611cb0ef41Sopenharmony_ci description: The property `context.importAssertions` is replaced with 4621cb0ef41Sopenharmony_ci `context.importAttributes`. Using the old name is still 4631cb0ef41Sopenharmony_ci supported and will emit an experimental warning. 4641cb0ef41Sopenharmony_ci - version: 4651cb0ef41Sopenharmony_ci - v18.6.0 4661cb0ef41Sopenharmony_ci - v16.17.0 4671cb0ef41Sopenharmony_ci pr-url: https://github.com/nodejs/node/pull/42623 4681cb0ef41Sopenharmony_ci description: Add support for chaining resolve hooks. Each hook must either 4691cb0ef41Sopenharmony_ci call `nextResolve()` or include a `shortCircuit` property set to `true` 4701cb0ef41Sopenharmony_ci in its return. 4711cb0ef41Sopenharmony_ci - version: 4721cb0ef41Sopenharmony_ci - v17.1.0 4731cb0ef41Sopenharmony_ci - v16.14.0 4741cb0ef41Sopenharmony_ci pr-url: https://github.com/nodejs/node/pull/40250 4751cb0ef41Sopenharmony_ci description: Add support for import assertions. 4761cb0ef41Sopenharmony_ci--> 4771cb0ef41Sopenharmony_ci 4781cb0ef41Sopenharmony_ci> Stability: 1.2 - Release candidate 4791cb0ef41Sopenharmony_ci 4801cb0ef41Sopenharmony_ci* `specifier` {string} 4811cb0ef41Sopenharmony_ci* `context` {Object} 4821cb0ef41Sopenharmony_ci * `conditions` {string\[]} Export conditions of the relevant `package.json` 4831cb0ef41Sopenharmony_ci * `importAttributes` {Object} An object whose key-value pairs represent the 4841cb0ef41Sopenharmony_ci attributes for the module to import 4851cb0ef41Sopenharmony_ci * `parentURL` {string|undefined} The module importing this one, or undefined 4861cb0ef41Sopenharmony_ci if this is the Node.js entry point 4871cb0ef41Sopenharmony_ci* `nextResolve` {Function} The subsequent `resolve` hook in the chain, or the 4881cb0ef41Sopenharmony_ci Node.js default `resolve` hook after the last user-supplied `resolve` hook 4891cb0ef41Sopenharmony_ci * `specifier` {string} 4901cb0ef41Sopenharmony_ci * `context` {Object} 4911cb0ef41Sopenharmony_ci* Returns: {Object|Promise} 4921cb0ef41Sopenharmony_ci * `format` {string|null|undefined} A hint to the load hook (it might be 4931cb0ef41Sopenharmony_ci ignored) 4941cb0ef41Sopenharmony_ci `'builtin' | 'commonjs' | 'json' | 'module' | 'wasm'` 4951cb0ef41Sopenharmony_ci * `importAttributes` {Object|undefined} The import attributes to use when 4961cb0ef41Sopenharmony_ci caching the module (optional; if excluded the input will be used) 4971cb0ef41Sopenharmony_ci * `shortCircuit` {undefined|boolean} A signal that this hook intends to 4981cb0ef41Sopenharmony_ci terminate the chain of `resolve` hooks. **Default:** `false` 4991cb0ef41Sopenharmony_ci * `url` {string} The absolute URL to which this input resolves 5001cb0ef41Sopenharmony_ci 5011cb0ef41Sopenharmony_ci> **Warning** Despite support for returning promises and async functions, calls 5021cb0ef41Sopenharmony_ci> to `resolve` may block the main thread which can impact performance. 5031cb0ef41Sopenharmony_ci 5041cb0ef41Sopenharmony_ciThe `resolve` hook chain is responsible for telling Node.js where to find and 5051cb0ef41Sopenharmony_cihow to cache a given `import` statement or expression, or `require` call. It can 5061cb0ef41Sopenharmony_cioptionally return a format (such as `'module'`) as a hint to the `load` hook. If 5071cb0ef41Sopenharmony_cia format is specified, the `load` hook is ultimately responsible for providing 5081cb0ef41Sopenharmony_cithe final `format` value (and it is free to ignore the hint provided by 5091cb0ef41Sopenharmony_ci`resolve`); if `resolve` provides a `format`, a custom `load` hook is required 5101cb0ef41Sopenharmony_cieven if only to pass the value to the Node.js default `load` hook. 5111cb0ef41Sopenharmony_ci 5121cb0ef41Sopenharmony_ciImport type attributes are part of the cache key for saving loaded modules into 5131cb0ef41Sopenharmony_cithe internal module cache. The `resolve` hook is responsible for returning an 5141cb0ef41Sopenharmony_ci`importAttributes` object if the module should be cached with different 5151cb0ef41Sopenharmony_ciattributes than were present in the source code. 5161cb0ef41Sopenharmony_ci 5171cb0ef41Sopenharmony_ciThe `conditions` property in `context` is an array of conditions for 5181cb0ef41Sopenharmony_ci[package exports conditions][Conditional exports] that apply to this resolution 5191cb0ef41Sopenharmony_cirequest. They can be used for looking up conditional mappings elsewhere or to 5201cb0ef41Sopenharmony_cimodify the list when calling the default resolution logic. 5211cb0ef41Sopenharmony_ci 5221cb0ef41Sopenharmony_ciThe current [package exports conditions][Conditional exports] are always in 5231cb0ef41Sopenharmony_cithe `context.conditions` array passed into the hook. To guarantee _default 5241cb0ef41Sopenharmony_ciNode.js module specifier resolution behavior_ when calling `defaultResolve`, the 5251cb0ef41Sopenharmony_ci`context.conditions` array passed to it _must_ include _all_ elements of the 5261cb0ef41Sopenharmony_ci`context.conditions` array originally passed into the `resolve` hook. 5271cb0ef41Sopenharmony_ci 5281cb0ef41Sopenharmony_ci```mjs 5291cb0ef41Sopenharmony_ciexport async function resolve(specifier, context, nextResolve) { 5301cb0ef41Sopenharmony_ci const { parentURL = null } = context; 5311cb0ef41Sopenharmony_ci 5321cb0ef41Sopenharmony_ci if (Math.random() > 0.5) { // Some condition. 5331cb0ef41Sopenharmony_ci // For some or all specifiers, do some custom logic for resolving. 5341cb0ef41Sopenharmony_ci // Always return an object of the form {url: <string>}. 5351cb0ef41Sopenharmony_ci return { 5361cb0ef41Sopenharmony_ci shortCircuit: true, 5371cb0ef41Sopenharmony_ci url: parentURL ? 5381cb0ef41Sopenharmony_ci new URL(specifier, parentURL).href : 5391cb0ef41Sopenharmony_ci new URL(specifier).href, 5401cb0ef41Sopenharmony_ci }; 5411cb0ef41Sopenharmony_ci } 5421cb0ef41Sopenharmony_ci 5431cb0ef41Sopenharmony_ci if (Math.random() < 0.5) { // Another condition. 5441cb0ef41Sopenharmony_ci // When calling `defaultResolve`, the arguments can be modified. In this 5451cb0ef41Sopenharmony_ci // case it's adding another value for matching conditional exports. 5461cb0ef41Sopenharmony_ci return nextResolve(specifier, { 5471cb0ef41Sopenharmony_ci ...context, 5481cb0ef41Sopenharmony_ci conditions: [...context.conditions, 'another-condition'], 5491cb0ef41Sopenharmony_ci }); 5501cb0ef41Sopenharmony_ci } 5511cb0ef41Sopenharmony_ci 5521cb0ef41Sopenharmony_ci // Defer to the next hook in the chain, which would be the 5531cb0ef41Sopenharmony_ci // Node.js default resolve if this is the last user-specified loader. 5541cb0ef41Sopenharmony_ci return nextResolve(specifier); 5551cb0ef41Sopenharmony_ci} 5561cb0ef41Sopenharmony_ci``` 5571cb0ef41Sopenharmony_ci 5581cb0ef41Sopenharmony_ci#### `load(url, context, nextLoad)` 5591cb0ef41Sopenharmony_ci 5601cb0ef41Sopenharmony_ci<!-- YAML 5611cb0ef41Sopenharmony_cichanges: 5621cb0ef41Sopenharmony_ci - version: 5631cb0ef41Sopenharmony_ci - v18.6.0 5641cb0ef41Sopenharmony_ci - v16.17.0 5651cb0ef41Sopenharmony_ci pr-url: https://github.com/nodejs/node/pull/42623 5661cb0ef41Sopenharmony_ci description: Add support for chaining load hooks. Each hook must either 5671cb0ef41Sopenharmony_ci call `nextLoad()` or include a `shortCircuit` property set to `true` in 5681cb0ef41Sopenharmony_ci its return. 5691cb0ef41Sopenharmony_ci--> 5701cb0ef41Sopenharmony_ci 5711cb0ef41Sopenharmony_ci> Stability: 1.2 - Release candidate 5721cb0ef41Sopenharmony_ci 5731cb0ef41Sopenharmony_ci* `url` {string} The URL returned by the `resolve` chain 5741cb0ef41Sopenharmony_ci* `context` {Object} 5751cb0ef41Sopenharmony_ci * `conditions` {string\[]} Export conditions of the relevant `package.json` 5761cb0ef41Sopenharmony_ci * `format` {string|null|undefined} The format optionally supplied by the 5771cb0ef41Sopenharmony_ci `resolve` hook chain 5781cb0ef41Sopenharmony_ci * `importAttributes` {Object} 5791cb0ef41Sopenharmony_ci* `nextLoad` {Function} The subsequent `load` hook in the chain, or the 5801cb0ef41Sopenharmony_ci Node.js default `load` hook after the last user-supplied `load` hook 5811cb0ef41Sopenharmony_ci * `specifier` {string} 5821cb0ef41Sopenharmony_ci * `context` {Object} 5831cb0ef41Sopenharmony_ci* Returns: {Object} 5841cb0ef41Sopenharmony_ci * `format` {string} 5851cb0ef41Sopenharmony_ci * `shortCircuit` {undefined|boolean} A signal that this hook intends to 5861cb0ef41Sopenharmony_ci terminate the chain of `resolve` hooks. **Default:** `false` 5871cb0ef41Sopenharmony_ci * `source` {string|ArrayBuffer|TypedArray} The source for Node.js to evaluate 5881cb0ef41Sopenharmony_ci 5891cb0ef41Sopenharmony_ciThe `load` hook provides a way to define a custom method of determining how a 5901cb0ef41Sopenharmony_ciURL should be interpreted, retrieved, and parsed. It is also in charge of 5911cb0ef41Sopenharmony_civalidating the import assertion. 5921cb0ef41Sopenharmony_ci 5931cb0ef41Sopenharmony_ciThe final value of `format` must be one of the following: 5941cb0ef41Sopenharmony_ci 5951cb0ef41Sopenharmony_ci| `format` | Description | Acceptable types for `source` returned by `load` | 5961cb0ef41Sopenharmony_ci| ------------ | ------------------------------ | ----------------------------------------------------- | 5971cb0ef41Sopenharmony_ci| `'builtin'` | Load a Node.js builtin module | Not applicable | 5981cb0ef41Sopenharmony_ci| `'commonjs'` | Load a Node.js CommonJS module | Not applicable | 5991cb0ef41Sopenharmony_ci| `'json'` | Load a JSON file | { [`string`][], [`ArrayBuffer`][], [`TypedArray`][] } | 6001cb0ef41Sopenharmony_ci| `'module'` | Load an ES module | { [`string`][], [`ArrayBuffer`][], [`TypedArray`][] } | 6011cb0ef41Sopenharmony_ci| `'wasm'` | Load a WebAssembly module | { [`ArrayBuffer`][], [`TypedArray`][] } | 6021cb0ef41Sopenharmony_ci 6031cb0ef41Sopenharmony_ciThe value of `source` is ignored for type `'builtin'` because currently it is 6041cb0ef41Sopenharmony_cinot possible to replace the value of a Node.js builtin (core) module. The value 6051cb0ef41Sopenharmony_ciof `source` is ignored for type `'commonjs'` because the CommonJS module loader 6061cb0ef41Sopenharmony_cidoes not provide a mechanism for the ES module loader to override the 6071cb0ef41Sopenharmony_ci[CommonJS module return value](esm.md#commonjs-namespaces). This limitation 6081cb0ef41Sopenharmony_cimight be overcome in the future. 6091cb0ef41Sopenharmony_ci 6101cb0ef41Sopenharmony_ci> **Warning**: The ESM `load` hook and namespaced exports from CommonJS modules 6111cb0ef41Sopenharmony_ci> are incompatible. Attempting to use them together will result in an empty 6121cb0ef41Sopenharmony_ci> object from the import. This may be addressed in the future. 6131cb0ef41Sopenharmony_ci 6141cb0ef41Sopenharmony_ci> These types all correspond to classes defined in ECMAScript. 6151cb0ef41Sopenharmony_ci 6161cb0ef41Sopenharmony_ci* The specific [`ArrayBuffer`][] object is a [`SharedArrayBuffer`][]. 6171cb0ef41Sopenharmony_ci* The specific [`TypedArray`][] object is a [`Uint8Array`][]. 6181cb0ef41Sopenharmony_ci 6191cb0ef41Sopenharmony_ciIf the source value of a text-based format (i.e., `'json'`, `'module'`) 6201cb0ef41Sopenharmony_ciis not a string, it is converted to a string using [`util.TextDecoder`][]. 6211cb0ef41Sopenharmony_ci 6221cb0ef41Sopenharmony_ciThe `load` hook provides a way to define a custom method for retrieving the 6231cb0ef41Sopenharmony_cisource code of a resolved URL. This would allow a loader to potentially avoid 6241cb0ef41Sopenharmony_cireading files from disk. It could also be used to map an unrecognized format to 6251cb0ef41Sopenharmony_cia supported one, for example `yaml` to `module`. 6261cb0ef41Sopenharmony_ci 6271cb0ef41Sopenharmony_ci```mjs 6281cb0ef41Sopenharmony_ciexport async function load(url, context, nextLoad) { 6291cb0ef41Sopenharmony_ci const { format } = context; 6301cb0ef41Sopenharmony_ci 6311cb0ef41Sopenharmony_ci if (Math.random() > 0.5) { // Some condition 6321cb0ef41Sopenharmony_ci /* 6331cb0ef41Sopenharmony_ci For some or all URLs, do some custom logic for retrieving the source. 6341cb0ef41Sopenharmony_ci Always return an object of the form { 6351cb0ef41Sopenharmony_ci format: <string>, 6361cb0ef41Sopenharmony_ci source: <string|buffer>, 6371cb0ef41Sopenharmony_ci }. 6381cb0ef41Sopenharmony_ci */ 6391cb0ef41Sopenharmony_ci return { 6401cb0ef41Sopenharmony_ci format, 6411cb0ef41Sopenharmony_ci shortCircuit: true, 6421cb0ef41Sopenharmony_ci source: '...', 6431cb0ef41Sopenharmony_ci }; 6441cb0ef41Sopenharmony_ci } 6451cb0ef41Sopenharmony_ci 6461cb0ef41Sopenharmony_ci // Defer to the next hook in the chain. 6471cb0ef41Sopenharmony_ci return nextLoad(url); 6481cb0ef41Sopenharmony_ci} 6491cb0ef41Sopenharmony_ci``` 6501cb0ef41Sopenharmony_ci 6511cb0ef41Sopenharmony_ciIn a more advanced scenario, this can also be used to transform an unsupported 6521cb0ef41Sopenharmony_cisource to a supported one (see [Examples](#examples) below). 6531cb0ef41Sopenharmony_ci 6541cb0ef41Sopenharmony_ci#### `globalPreload()` 6551cb0ef41Sopenharmony_ci 6561cb0ef41Sopenharmony_ci<!-- YAML 6571cb0ef41Sopenharmony_cichanges: 6581cb0ef41Sopenharmony_ci - version: 6591cb0ef41Sopenharmony_ci - v18.6.0 6601cb0ef41Sopenharmony_ci - v16.17.0 6611cb0ef41Sopenharmony_ci pr-url: https://github.com/nodejs/node/pull/42623 6621cb0ef41Sopenharmony_ci description: Add support for chaining globalPreload hooks. 6631cb0ef41Sopenharmony_ci--> 6641cb0ef41Sopenharmony_ci 6651cb0ef41Sopenharmony_ci> Stability: 1.0 - Early development 6661cb0ef41Sopenharmony_ci 6671cb0ef41Sopenharmony_ci> **Warning:** This hook will be removed in a future version. Use 6681cb0ef41Sopenharmony_ci> [`initialize`][] instead. When a hooks module has an `initialize` export, 6691cb0ef41Sopenharmony_ci> `globalPreload` will be ignored. 6701cb0ef41Sopenharmony_ci 6711cb0ef41Sopenharmony_ci* `context` {Object} Information to assist the preload code 6721cb0ef41Sopenharmony_ci * `port` {MessagePort} 6731cb0ef41Sopenharmony_ci* Returns: {string} Code to run before application startup 6741cb0ef41Sopenharmony_ci 6751cb0ef41Sopenharmony_ciSometimes it might be necessary to run some code inside of the same global 6761cb0ef41Sopenharmony_ciscope that the application runs in. This hook allows the return of a string 6771cb0ef41Sopenharmony_cithat is run as a sloppy-mode script on startup. 6781cb0ef41Sopenharmony_ci 6791cb0ef41Sopenharmony_ciSimilar to how CommonJS wrappers work, the code runs in an implicit function 6801cb0ef41Sopenharmony_ciscope. The only argument is a `require`-like function that can be used to load 6811cb0ef41Sopenharmony_cibuiltins like "fs": `getBuiltin(request: string)`. 6821cb0ef41Sopenharmony_ci 6831cb0ef41Sopenharmony_ciIf the code needs more advanced `require` features, it has to construct 6841cb0ef41Sopenharmony_ciits own `require` using `module.createRequire()`. 6851cb0ef41Sopenharmony_ci 6861cb0ef41Sopenharmony_ci```mjs 6871cb0ef41Sopenharmony_ciexport function globalPreload(context) { 6881cb0ef41Sopenharmony_ci return `\ 6891cb0ef41Sopenharmony_ciglobalThis.someInjectedProperty = 42; 6901cb0ef41Sopenharmony_ciconsole.log('I just set some globals!'); 6911cb0ef41Sopenharmony_ci 6921cb0ef41Sopenharmony_ciconst { createRequire } = getBuiltin('module'); 6931cb0ef41Sopenharmony_ciconst { cwd } = getBuiltin('process'); 6941cb0ef41Sopenharmony_ci 6951cb0ef41Sopenharmony_ciconst require = createRequire(cwd() + '/<preload>'); 6961cb0ef41Sopenharmony_ci// [...] 6971cb0ef41Sopenharmony_ci`; 6981cb0ef41Sopenharmony_ci} 6991cb0ef41Sopenharmony_ci``` 7001cb0ef41Sopenharmony_ci 7011cb0ef41Sopenharmony_ciAnother argument is provided to the preload code: `port`. This is available as a 7021cb0ef41Sopenharmony_ciparameter to the hook and inside of the source text returned by the hook. This 7031cb0ef41Sopenharmony_cifunctionality has been moved to the `initialize` hook. 7041cb0ef41Sopenharmony_ci 7051cb0ef41Sopenharmony_ciCare must be taken in order to properly call [`port.ref()`][] and 7061cb0ef41Sopenharmony_ci[`port.unref()`][] to prevent a process from being in a state where it won't 7071cb0ef41Sopenharmony_ciclose normally. 7081cb0ef41Sopenharmony_ci 7091cb0ef41Sopenharmony_ci```mjs 7101cb0ef41Sopenharmony_ci/** 7111cb0ef41Sopenharmony_ci * This example has the application context send a message to the hook 7121cb0ef41Sopenharmony_ci * and sends the message back to the application context 7131cb0ef41Sopenharmony_ci */ 7141cb0ef41Sopenharmony_ciexport function globalPreload({ port }) { 7151cb0ef41Sopenharmony_ci port.on('message', (msg) => { 7161cb0ef41Sopenharmony_ci port.postMessage(msg); 7171cb0ef41Sopenharmony_ci }); 7181cb0ef41Sopenharmony_ci return `\ 7191cb0ef41Sopenharmony_ci port.postMessage('console.log("I went to the hook and back");'); 7201cb0ef41Sopenharmony_ci port.on('message', (msg) => { 7211cb0ef41Sopenharmony_ci eval(msg); 7221cb0ef41Sopenharmony_ci }); 7231cb0ef41Sopenharmony_ci `; 7241cb0ef41Sopenharmony_ci} 7251cb0ef41Sopenharmony_ci``` 7261cb0ef41Sopenharmony_ci 7271cb0ef41Sopenharmony_ci### Examples 7281cb0ef41Sopenharmony_ci 7291cb0ef41Sopenharmony_ciThe various module customization hooks can be used together to accomplish 7301cb0ef41Sopenharmony_ciwide-ranging customizations of the Node.js code loading and evaluation 7311cb0ef41Sopenharmony_cibehaviors. 7321cb0ef41Sopenharmony_ci 7331cb0ef41Sopenharmony_ci#### Import from HTTPS 7341cb0ef41Sopenharmony_ci 7351cb0ef41Sopenharmony_ciIn current Node.js, specifiers starting with `https://` are experimental (see 7361cb0ef41Sopenharmony_ci[HTTPS and HTTP imports][]). 7371cb0ef41Sopenharmony_ci 7381cb0ef41Sopenharmony_ciThe hook below registers hooks to enable rudimentary support for such 7391cb0ef41Sopenharmony_cispecifiers. While this may seem like a significant improvement to Node.js core 7401cb0ef41Sopenharmony_cifunctionality, there are substantial downsides to actually using these hooks: 7411cb0ef41Sopenharmony_ciperformance is much slower than loading files from disk, there is no caching, 7421cb0ef41Sopenharmony_ciand there is no security. 7431cb0ef41Sopenharmony_ci 7441cb0ef41Sopenharmony_ci```mjs 7451cb0ef41Sopenharmony_ci// https-hooks.mjs 7461cb0ef41Sopenharmony_ciimport { get } from 'node:https'; 7471cb0ef41Sopenharmony_ci 7481cb0ef41Sopenharmony_ciexport function load(url, context, nextLoad) { 7491cb0ef41Sopenharmony_ci // For JavaScript to be loaded over the network, we need to fetch and 7501cb0ef41Sopenharmony_ci // return it. 7511cb0ef41Sopenharmony_ci if (url.startsWith('https://')) { 7521cb0ef41Sopenharmony_ci return new Promise((resolve, reject) => { 7531cb0ef41Sopenharmony_ci get(url, (res) => { 7541cb0ef41Sopenharmony_ci let data = ''; 7551cb0ef41Sopenharmony_ci res.setEncoding('utf8'); 7561cb0ef41Sopenharmony_ci res.on('data', (chunk) => data += chunk); 7571cb0ef41Sopenharmony_ci res.on('end', () => resolve({ 7581cb0ef41Sopenharmony_ci // This example assumes all network-provided JavaScript is ES module 7591cb0ef41Sopenharmony_ci // code. 7601cb0ef41Sopenharmony_ci format: 'module', 7611cb0ef41Sopenharmony_ci shortCircuit: true, 7621cb0ef41Sopenharmony_ci source: data, 7631cb0ef41Sopenharmony_ci })); 7641cb0ef41Sopenharmony_ci }).on('error', (err) => reject(err)); 7651cb0ef41Sopenharmony_ci }); 7661cb0ef41Sopenharmony_ci } 7671cb0ef41Sopenharmony_ci 7681cb0ef41Sopenharmony_ci // Let Node.js handle all other URLs. 7691cb0ef41Sopenharmony_ci return nextLoad(url); 7701cb0ef41Sopenharmony_ci} 7711cb0ef41Sopenharmony_ci``` 7721cb0ef41Sopenharmony_ci 7731cb0ef41Sopenharmony_ci```mjs 7741cb0ef41Sopenharmony_ci// main.mjs 7751cb0ef41Sopenharmony_ciimport { VERSION } from 'https://coffeescript.org/browser-compiler-modern/coffeescript.js'; 7761cb0ef41Sopenharmony_ci 7771cb0ef41Sopenharmony_ciconsole.log(VERSION); 7781cb0ef41Sopenharmony_ci``` 7791cb0ef41Sopenharmony_ci 7801cb0ef41Sopenharmony_ciWith the preceding hooks module, running 7811cb0ef41Sopenharmony_ci`node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register(pathToFileURL("./https-hooks.mjs"));' ./main.mjs` 7821cb0ef41Sopenharmony_ciprints the current version of CoffeeScript per the module at the URL in 7831cb0ef41Sopenharmony_ci`main.mjs`. 7841cb0ef41Sopenharmony_ci 7851cb0ef41Sopenharmony_ci#### Transpilation 7861cb0ef41Sopenharmony_ci 7871cb0ef41Sopenharmony_ciSources that are in formats Node.js doesn't understand can be converted into 7881cb0ef41Sopenharmony_ciJavaScript using the [`load` hook][load hook]. 7891cb0ef41Sopenharmony_ci 7901cb0ef41Sopenharmony_ciThis is less performant than transpiling source files before running Node.js; 7911cb0ef41Sopenharmony_citranspiler hooks should only be used for development and testing purposes. 7921cb0ef41Sopenharmony_ci 7931cb0ef41Sopenharmony_ci```mjs 7941cb0ef41Sopenharmony_ci// coffeescript-hooks.mjs 7951cb0ef41Sopenharmony_ciimport { readFile } from 'node:fs/promises'; 7961cb0ef41Sopenharmony_ciimport { dirname, extname, resolve as resolvePath } from 'node:path'; 7971cb0ef41Sopenharmony_ciimport { cwd } from 'node:process'; 7981cb0ef41Sopenharmony_ciimport { fileURLToPath, pathToFileURL } from 'node:url'; 7991cb0ef41Sopenharmony_ciimport coffeescript from 'coffeescript'; 8001cb0ef41Sopenharmony_ci 8011cb0ef41Sopenharmony_ciconst extensionsRegex = /\.(coffee|litcoffee|coffee\.md)$/; 8021cb0ef41Sopenharmony_ci 8031cb0ef41Sopenharmony_ciexport async function load(url, context, nextLoad) { 8041cb0ef41Sopenharmony_ci if (extensionsRegex.test(url)) { 8051cb0ef41Sopenharmony_ci // CoffeeScript files can be either CommonJS or ES modules, so we want any 8061cb0ef41Sopenharmony_ci // CoffeeScript file to be treated by Node.js the same as a .js file at the 8071cb0ef41Sopenharmony_ci // same location. To determine how Node.js would interpret an arbitrary .js 8081cb0ef41Sopenharmony_ci // file, search up the file system for the nearest parent package.json file 8091cb0ef41Sopenharmony_ci // and read its "type" field. 8101cb0ef41Sopenharmony_ci const format = await getPackageType(url); 8111cb0ef41Sopenharmony_ci 8121cb0ef41Sopenharmony_ci const { source: rawSource } = await nextLoad(url, { ...context, format }); 8131cb0ef41Sopenharmony_ci // This hook converts CoffeeScript source code into JavaScript source code 8141cb0ef41Sopenharmony_ci // for all imported CoffeeScript files. 8151cb0ef41Sopenharmony_ci const transformedSource = coffeescript.compile(rawSource.toString(), url); 8161cb0ef41Sopenharmony_ci 8171cb0ef41Sopenharmony_ci return { 8181cb0ef41Sopenharmony_ci format, 8191cb0ef41Sopenharmony_ci shortCircuit: true, 8201cb0ef41Sopenharmony_ci source: transformedSource, 8211cb0ef41Sopenharmony_ci }; 8221cb0ef41Sopenharmony_ci } 8231cb0ef41Sopenharmony_ci 8241cb0ef41Sopenharmony_ci // Let Node.js handle all other URLs. 8251cb0ef41Sopenharmony_ci return nextLoad(url); 8261cb0ef41Sopenharmony_ci} 8271cb0ef41Sopenharmony_ci 8281cb0ef41Sopenharmony_ciasync function getPackageType(url) { 8291cb0ef41Sopenharmony_ci // `url` is only a file path during the first iteration when passed the 8301cb0ef41Sopenharmony_ci // resolved url from the load() hook 8311cb0ef41Sopenharmony_ci // an actual file path from load() will contain a file extension as it's 8321cb0ef41Sopenharmony_ci // required by the spec 8331cb0ef41Sopenharmony_ci // this simple truthy check for whether `url` contains a file extension will 8341cb0ef41Sopenharmony_ci // work for most projects but does not cover some edge-cases (such as 8351cb0ef41Sopenharmony_ci // extensionless files or a url ending in a trailing space) 8361cb0ef41Sopenharmony_ci const isFilePath = !!extname(url); 8371cb0ef41Sopenharmony_ci // If it is a file path, get the directory it's in 8381cb0ef41Sopenharmony_ci const dir = isFilePath ? 8391cb0ef41Sopenharmony_ci dirname(fileURLToPath(url)) : 8401cb0ef41Sopenharmony_ci url; 8411cb0ef41Sopenharmony_ci // Compose a file path to a package.json in the same directory, 8421cb0ef41Sopenharmony_ci // which may or may not exist 8431cb0ef41Sopenharmony_ci const packagePath = resolvePath(dir, 'package.json'); 8441cb0ef41Sopenharmony_ci // Try to read the possibly nonexistent package.json 8451cb0ef41Sopenharmony_ci const type = await readFile(packagePath, { encoding: 'utf8' }) 8461cb0ef41Sopenharmony_ci .then((filestring) => JSON.parse(filestring).type) 8471cb0ef41Sopenharmony_ci .catch((err) => { 8481cb0ef41Sopenharmony_ci if (err?.code !== 'ENOENT') console.error(err); 8491cb0ef41Sopenharmony_ci }); 8501cb0ef41Sopenharmony_ci // Ff package.json existed and contained a `type` field with a value, voila 8511cb0ef41Sopenharmony_ci if (type) return type; 8521cb0ef41Sopenharmony_ci // Otherwise, (if not at the root) continue checking the next directory up 8531cb0ef41Sopenharmony_ci // If at the root, stop and return false 8541cb0ef41Sopenharmony_ci return dir.length > 1 && getPackageType(resolvePath(dir, '..')); 8551cb0ef41Sopenharmony_ci} 8561cb0ef41Sopenharmony_ci``` 8571cb0ef41Sopenharmony_ci 8581cb0ef41Sopenharmony_ci```coffee 8591cb0ef41Sopenharmony_ci# main.coffee 8601cb0ef41Sopenharmony_ciimport { scream } from './scream.coffee' 8611cb0ef41Sopenharmony_ciconsole.log scream 'hello, world' 8621cb0ef41Sopenharmony_ci 8631cb0ef41Sopenharmony_ciimport { version } from 'node:process' 8641cb0ef41Sopenharmony_ciconsole.log "Brought to you by Node.js version #{version}" 8651cb0ef41Sopenharmony_ci``` 8661cb0ef41Sopenharmony_ci 8671cb0ef41Sopenharmony_ci```coffee 8681cb0ef41Sopenharmony_ci# scream.coffee 8691cb0ef41Sopenharmony_ciexport scream = (str) -> str.toUpperCase() 8701cb0ef41Sopenharmony_ci``` 8711cb0ef41Sopenharmony_ci 8721cb0ef41Sopenharmony_ciWith the preceding hooks module, running 8731cb0ef41Sopenharmony_ci`node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register(pathToFileURL("./coffeescript-hooks.mjs"));' ./main.coffee` 8741cb0ef41Sopenharmony_cicauses `main.coffee` to be turned into JavaScript after its source code is 8751cb0ef41Sopenharmony_ciloaded from disk but before Node.js executes it; and so on for any `.coffee`, 8761cb0ef41Sopenharmony_ci`.litcoffee` or `.coffee.md` files referenced via `import` statements of any 8771cb0ef41Sopenharmony_ciloaded file. 8781cb0ef41Sopenharmony_ci 8791cb0ef41Sopenharmony_ci#### Import maps 8801cb0ef41Sopenharmony_ci 8811cb0ef41Sopenharmony_ciThe previous two examples defined `load` hooks. This is an example of a 8821cb0ef41Sopenharmony_ci`resolve` hook. This hooks module reads an `import-map.json` file that defines 8831cb0ef41Sopenharmony_ciwhich specifiers to override to other URLs (this is a very simplistic 8841cb0ef41Sopenharmony_ciimplementation of a small subset of the "import maps" specification). 8851cb0ef41Sopenharmony_ci 8861cb0ef41Sopenharmony_ci```mjs 8871cb0ef41Sopenharmony_ci// import-map-hooks.js 8881cb0ef41Sopenharmony_ciimport fs from 'node:fs/promises'; 8891cb0ef41Sopenharmony_ci 8901cb0ef41Sopenharmony_ciconst { imports } = JSON.parse(await fs.readFile('import-map.json')); 8911cb0ef41Sopenharmony_ci 8921cb0ef41Sopenharmony_ciexport async function resolve(specifier, context, nextResolve) { 8931cb0ef41Sopenharmony_ci if (Object.hasOwn(imports, specifier)) { 8941cb0ef41Sopenharmony_ci return nextResolve(imports[specifier], context); 8951cb0ef41Sopenharmony_ci } 8961cb0ef41Sopenharmony_ci 8971cb0ef41Sopenharmony_ci return nextResolve(specifier, context); 8981cb0ef41Sopenharmony_ci} 8991cb0ef41Sopenharmony_ci``` 9001cb0ef41Sopenharmony_ci 9011cb0ef41Sopenharmony_ciWith these files: 9021cb0ef41Sopenharmony_ci 9031cb0ef41Sopenharmony_ci```mjs 9041cb0ef41Sopenharmony_ci// main.js 9051cb0ef41Sopenharmony_ciimport 'a-module'; 9061cb0ef41Sopenharmony_ci``` 9071cb0ef41Sopenharmony_ci 9081cb0ef41Sopenharmony_ci```json 9091cb0ef41Sopenharmony_ci// import-map.json 9101cb0ef41Sopenharmony_ci{ 9111cb0ef41Sopenharmony_ci "imports": { 9121cb0ef41Sopenharmony_ci "a-module": "./some-module.js" 9131cb0ef41Sopenharmony_ci } 9141cb0ef41Sopenharmony_ci} 9151cb0ef41Sopenharmony_ci``` 9161cb0ef41Sopenharmony_ci 9171cb0ef41Sopenharmony_ci```mjs 9181cb0ef41Sopenharmony_ci// some-module.js 9191cb0ef41Sopenharmony_ciconsole.log('some module!'); 9201cb0ef41Sopenharmony_ci``` 9211cb0ef41Sopenharmony_ci 9221cb0ef41Sopenharmony_ciRunning `node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register(pathToFileURL("./import-map-hooks.js"));' main.js` 9231cb0ef41Sopenharmony_cishould print `some module!`. 9241cb0ef41Sopenharmony_ci 9251cb0ef41Sopenharmony_ci## Source map v3 support 9261cb0ef41Sopenharmony_ci 9271cb0ef41Sopenharmony_ci<!-- YAML 9281cb0ef41Sopenharmony_ciadded: 9291cb0ef41Sopenharmony_ci - v13.7.0 9301cb0ef41Sopenharmony_ci - v12.17.0 9311cb0ef41Sopenharmony_ci--> 9321cb0ef41Sopenharmony_ci 9331cb0ef41Sopenharmony_ci> Stability: 1 - Experimental 9341cb0ef41Sopenharmony_ci 9351cb0ef41Sopenharmony_ciHelpers for interacting with the source map cache. This cache is 9361cb0ef41Sopenharmony_cipopulated when source map parsing is enabled and 9371cb0ef41Sopenharmony_ci[source map include directives][] are found in a modules' footer. 9381cb0ef41Sopenharmony_ci 9391cb0ef41Sopenharmony_ciTo enable source map parsing, Node.js must be run with the flag 9401cb0ef41Sopenharmony_ci[`--enable-source-maps`][], or with code coverage enabled by setting 9411cb0ef41Sopenharmony_ci[`NODE_V8_COVERAGE=dir`][]. 9421cb0ef41Sopenharmony_ci 9431cb0ef41Sopenharmony_ci```mjs 9441cb0ef41Sopenharmony_ci// module.mjs 9451cb0ef41Sopenharmony_ci// In an ECMAScript module 9461cb0ef41Sopenharmony_ciimport { findSourceMap, SourceMap } from 'node:module'; 9471cb0ef41Sopenharmony_ci``` 9481cb0ef41Sopenharmony_ci 9491cb0ef41Sopenharmony_ci```cjs 9501cb0ef41Sopenharmony_ci// module.cjs 9511cb0ef41Sopenharmony_ci// In a CommonJS module 9521cb0ef41Sopenharmony_ciconst { findSourceMap, SourceMap } = require('node:module'); 9531cb0ef41Sopenharmony_ci``` 9541cb0ef41Sopenharmony_ci 9551cb0ef41Sopenharmony_ci<!-- Anchors to make sure old links find a target --> 9561cb0ef41Sopenharmony_ci 9571cb0ef41Sopenharmony_ci<a id="module_module_findsourcemap_path_error"></a> 9581cb0ef41Sopenharmony_ci 9591cb0ef41Sopenharmony_ci### `module.findSourceMap(path)` 9601cb0ef41Sopenharmony_ci 9611cb0ef41Sopenharmony_ci<!-- YAML 9621cb0ef41Sopenharmony_ciadded: 9631cb0ef41Sopenharmony_ci - v13.7.0 9641cb0ef41Sopenharmony_ci - v12.17.0 9651cb0ef41Sopenharmony_ci--> 9661cb0ef41Sopenharmony_ci 9671cb0ef41Sopenharmony_ci* `path` {string} 9681cb0ef41Sopenharmony_ci* Returns: {module.SourceMap|undefined} Returns `module.SourceMap` if a source 9691cb0ef41Sopenharmony_ci map is found, `undefined` otherwise. 9701cb0ef41Sopenharmony_ci 9711cb0ef41Sopenharmony_ci`path` is the resolved path for the file for which a corresponding source map 9721cb0ef41Sopenharmony_cishould be fetched. 9731cb0ef41Sopenharmony_ci 9741cb0ef41Sopenharmony_ci### Class: `module.SourceMap` 9751cb0ef41Sopenharmony_ci 9761cb0ef41Sopenharmony_ci<!-- YAML 9771cb0ef41Sopenharmony_ciadded: 9781cb0ef41Sopenharmony_ci - v13.7.0 9791cb0ef41Sopenharmony_ci - v12.17.0 9801cb0ef41Sopenharmony_ci--> 9811cb0ef41Sopenharmony_ci 9821cb0ef41Sopenharmony_ci#### `new SourceMap(payload)` 9831cb0ef41Sopenharmony_ci 9841cb0ef41Sopenharmony_ci* `payload` {Object} 9851cb0ef41Sopenharmony_ci 9861cb0ef41Sopenharmony_ciCreates a new `sourceMap` instance. 9871cb0ef41Sopenharmony_ci 9881cb0ef41Sopenharmony_ci`payload` is an object with keys matching the [Source map v3 format][]: 9891cb0ef41Sopenharmony_ci 9901cb0ef41Sopenharmony_ci* `file`: {string} 9911cb0ef41Sopenharmony_ci* `version`: {number} 9921cb0ef41Sopenharmony_ci* `sources`: {string\[]} 9931cb0ef41Sopenharmony_ci* `sourcesContent`: {string\[]} 9941cb0ef41Sopenharmony_ci* `names`: {string\[]} 9951cb0ef41Sopenharmony_ci* `mappings`: {string} 9961cb0ef41Sopenharmony_ci* `sourceRoot`: {string} 9971cb0ef41Sopenharmony_ci 9981cb0ef41Sopenharmony_ci#### `sourceMap.payload` 9991cb0ef41Sopenharmony_ci 10001cb0ef41Sopenharmony_ci* Returns: {Object} 10011cb0ef41Sopenharmony_ci 10021cb0ef41Sopenharmony_ciGetter for the payload used to construct the [`SourceMap`][] instance. 10031cb0ef41Sopenharmony_ci 10041cb0ef41Sopenharmony_ci#### `sourceMap.findEntry(lineOffset, columnOffset)` 10051cb0ef41Sopenharmony_ci 10061cb0ef41Sopenharmony_ci* `lineOffset` {number} The zero-indexed line number offset in 10071cb0ef41Sopenharmony_ci the generated source 10081cb0ef41Sopenharmony_ci* `columnOffset` {number} The zero-indexed column number offset 10091cb0ef41Sopenharmony_ci in the generated source 10101cb0ef41Sopenharmony_ci* Returns: {Object} 10111cb0ef41Sopenharmony_ci 10121cb0ef41Sopenharmony_ciGiven a line offset and column offset in the generated source 10131cb0ef41Sopenharmony_cifile, returns an object representing the SourceMap range in the 10141cb0ef41Sopenharmony_cioriginal file if found, or an empty object if not. 10151cb0ef41Sopenharmony_ci 10161cb0ef41Sopenharmony_ciThe object returned contains the following keys: 10171cb0ef41Sopenharmony_ci 10181cb0ef41Sopenharmony_ci* generatedLine: {number} The line offset of the start of the 10191cb0ef41Sopenharmony_ci range in the generated source 10201cb0ef41Sopenharmony_ci* generatedColumn: {number} The column offset of start of the 10211cb0ef41Sopenharmony_ci range in the generated source 10221cb0ef41Sopenharmony_ci* originalSource: {string} The file name of the original source, 10231cb0ef41Sopenharmony_ci as reported in the SourceMap 10241cb0ef41Sopenharmony_ci* originalLine: {number} The line offset of the start of the 10251cb0ef41Sopenharmony_ci range in the original source 10261cb0ef41Sopenharmony_ci* originalColumn: {number} The column offset of start of the 10271cb0ef41Sopenharmony_ci range in the original source 10281cb0ef41Sopenharmony_ci* name: {string} 10291cb0ef41Sopenharmony_ci 10301cb0ef41Sopenharmony_ciThe returned value represents the raw range as it appears in the 10311cb0ef41Sopenharmony_ciSourceMap, based on zero-indexed offsets, _not_ 1-indexed line and 10321cb0ef41Sopenharmony_cicolumn numbers as they appear in Error messages and CallSite 10331cb0ef41Sopenharmony_ciobjects. 10341cb0ef41Sopenharmony_ci 10351cb0ef41Sopenharmony_ciTo get the corresponding 1-indexed line and column numbers from a 10361cb0ef41Sopenharmony_cilineNumber and columnNumber as they are reported by Error stacks 10371cb0ef41Sopenharmony_ciand CallSite objects, use `sourceMap.findOrigin(lineNumber, 10381cb0ef41Sopenharmony_cicolumnNumber)` 10391cb0ef41Sopenharmony_ci 10401cb0ef41Sopenharmony_ci#### `sourceMap.findOrigin(lineNumber, columnNumber)` 10411cb0ef41Sopenharmony_ci 10421cb0ef41Sopenharmony_ci* `lineNumber` {number} The 1-indexed line number of the call 10431cb0ef41Sopenharmony_ci site in the generated source 10441cb0ef41Sopenharmony_ci* `columnOffset` {number} The 1-indexed column number 10451cb0ef41Sopenharmony_ci of the call site in the generated source 10461cb0ef41Sopenharmony_ci* Returns: {Object} 10471cb0ef41Sopenharmony_ci 10481cb0ef41Sopenharmony_ciGiven a 1-indexed lineNumber and columnNumber from a call site in 10491cb0ef41Sopenharmony_cithe generated source, find the corresponding call site location 10501cb0ef41Sopenharmony_ciin the original source. 10511cb0ef41Sopenharmony_ci 10521cb0ef41Sopenharmony_ciIf the lineNumber and columnNumber provided are not found in any 10531cb0ef41Sopenharmony_cisource map, then an empty object is returned. Otherwise, the 10541cb0ef41Sopenharmony_cireturned object contains the following keys: 10551cb0ef41Sopenharmony_ci 10561cb0ef41Sopenharmony_ci* name: {string | undefined} The name of the range in the 10571cb0ef41Sopenharmony_ci source map, if one was provided 10581cb0ef41Sopenharmony_ci* fileName: {string} The file name of the original source, as 10591cb0ef41Sopenharmony_ci reported in the SourceMap 10601cb0ef41Sopenharmony_ci* lineNumber: {number} The 1-indexed lineNumber of the 10611cb0ef41Sopenharmony_ci corresponding call site in the original source 10621cb0ef41Sopenharmony_ci* columnNumber: {number} The 1-indexed columnNumber of the 10631cb0ef41Sopenharmony_ci corresponding call site in the original source 10641cb0ef41Sopenharmony_ci 10651cb0ef41Sopenharmony_ci[CommonJS]: modules.md 10661cb0ef41Sopenharmony_ci[Conditional exports]: packages.md#conditional-exports 10671cb0ef41Sopenharmony_ci[Customization hooks]: #customization-hooks 10681cb0ef41Sopenharmony_ci[ES Modules]: esm.md 10691cb0ef41Sopenharmony_ci[HTTPS and HTTP imports]: esm.md#https-and-http-imports 10701cb0ef41Sopenharmony_ci[Source map v3 format]: https://sourcemaps.info/spec.html#h.mofvlxcwqzej 10711cb0ef41Sopenharmony_ci[`"exports"`]: packages.md#exports 10721cb0ef41Sopenharmony_ci[`--enable-source-maps`]: cli.md#--enable-source-maps 10731cb0ef41Sopenharmony_ci[`ArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer 10741cb0ef41Sopenharmony_ci[`NODE_V8_COVERAGE=dir`]: cli.md#node_v8_coveragedir 10751cb0ef41Sopenharmony_ci[`SharedArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer 10761cb0ef41Sopenharmony_ci[`SourceMap`]: #class-modulesourcemap 10771cb0ef41Sopenharmony_ci[`TypedArray`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray 10781cb0ef41Sopenharmony_ci[`Uint8Array`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array 10791cb0ef41Sopenharmony_ci[`initialize`]: #initialize 10801cb0ef41Sopenharmony_ci[`module`]: modules.md#the-module-object 10811cb0ef41Sopenharmony_ci[`port.ref()`]: worker_threads.md#portref 10821cb0ef41Sopenharmony_ci[`port.unref()`]: worker_threads.md#portunref 10831cb0ef41Sopenharmony_ci[`register`]: #moduleregisterspecifier-parenturl-options 10841cb0ef41Sopenharmony_ci[`string`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String 10851cb0ef41Sopenharmony_ci[`util.TextDecoder`]: util.md#class-utiltextdecoder 10861cb0ef41Sopenharmony_ci[hooks]: #customization-hooks 10871cb0ef41Sopenharmony_ci[load hook]: #loadurl-context-nextload 10881cb0ef41Sopenharmony_ci[module wrapper]: modules.md#the-module-wrapper 10891cb0ef41Sopenharmony_ci[realm]: https://tc39.es/ecma262/#realm 10901cb0ef41Sopenharmony_ci[source map include directives]: https://sourcemaps.info/spec.html#h.lmz475t4mvbx 10911cb0ef41Sopenharmony_ci[transferrable objects]: worker_threads.md#portpostmessagevalue-transferlist 1092