diff --git a/doc/api/esm.md b/doc/api/esm.md index 7a5c053f317d5b..3be5e9a3d37873 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -293,12 +293,12 @@ mandatory: | ---------------- | ---------------- | | `'json'` | [JSON modules][] | -## Builtin modules +## Built-in modules -[Core modules][] provide named exports of their public API. A +[Built-in modules][] provide named exports of their public API. A default export is also provided which is the value of the CommonJS exports. The default export can be used for, among other things, modifying the named -exports. Named exports of builtin modules are updated only by calling +exports. Named exports of built-in modules are updated only by calling [`module.syncBuiltinESMExports()`][]. ```js @@ -1145,8 +1145,8 @@ resolution for ESM specifiers is [commonjs-extension-resolution-loader][]. [6.1.7 Array Index]: https://tc39.es/ecma262/#integer-index [Addons]: addons.md +[Built-in modules]: modules.md#built-in-modules [CommonJS]: modules.md -[Core modules]: modules.md#core-modules [Determining module system]: packages.md#determining-module-system [Dynamic `import()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import [ES Module Integration Proposal for WebAssembly]: https://github.com/webassembly/esm-integration diff --git a/doc/api/modules.md b/doc/api/modules.md index e04eef782f2143..b772632d71256f 100644 --- a/doc/api/modules.md +++ b/doc/api/modules.md @@ -380,7 +380,7 @@ them as different modules and will reload the file multiple times. For example, `require('./foo')` and `require('./FOO')` return two different objects, irrespective of whether or not `./foo` and `./FOO` are the same file. -## Core modules +## Built-in modules @@ -396,20 +396,31 @@ changes: Node.js has several modules compiled into the binary. These modules are described in greater detail elsewhere in this documentation. -The core modules are defined within the Node.js source and are located in the +The built-in modules are defined within the Node.js source and are located in the `lib/` folder. -Core modules can be identified using the `node:` prefix, in which case +built-in modules can be identified using the `node:` prefix, in which case it bypasses the `require` cache. For instance, `require('node:http')` will always return the built in HTTP module, even if there is `require.cache` entry by that name. -Some core modules are always preferentially loaded if their identifier is +Some built-in modules are always preferentially loaded if their identifier is passed to `require()`. For instance, `require('http')` will always return the built-in HTTP module, even if there is a file by that name. The list -of core modules that can be loaded without using the `node:` prefix is exposed +of built-in modules that can be loaded without using the `node:` prefix is exposed as [`module.builtinModules`][]. +### Built-in modules with mandatory `node:` prefix + +When being loaded by `require()`, some built-in modules must be requested with the +`node:` prefix. This requirement exists to prevent newly introduced built-in +modules from having a conflict with user land packages that already have +taken the name. Currently the built-in modules that requires the `node:` prefix are: + +* [`node:sea`][] +* [`node:test`][] +* [`node:test/reporters`][] + ## Cycles @@ -552,7 +563,7 @@ folders as modules, and work for both `require` and `import`. If the module identifier passed to `require()` is not a -[core](#core-modules) module, and does not begin with `'/'`, `'../'`, or +[built-in](#built-in-modules) module, and does not begin with `'/'`, `'../'`, or `'./'`, then Node.js starts at the directory of the current module, and adds `/node_modules`, and attempts to load the module from that location. Node.js will not append `node_modules` to a path already ending in @@ -1166,6 +1177,9 @@ This section was moved to [`module.id`]: #moduleid [`module` core module]: module.md [`module` object]: #the-module-object +[`node:sea`]: single-executable-applications.md#single-executable-application-api +[`node:test/reporters`]: test.md#test-reporters +[`node:test`]: test.md [`package.json`]: packages.md#nodejs-packagejson-field-definitions [`path.dirname()`]: path.md#pathdirnamepath [`require.main`]: #requiremain diff --git a/doc/api/process.md b/doc/api/process.md index 878b14f7ef97b1..f3b3eab2d0a703 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -1917,6 +1917,46 @@ console.log('After:', getActiveResourcesInfo()); // After: [ 'TTYWrap', 'TTYWrap', 'TTYWrap', 'Timeout' ] ``` +## `process.getBuiltinModule(id)` + + + +* `id` {string} ID of the built-in module being requested. +* Returns: {Object|undefined} + +`process.getBuiltinModule(id)` provides a way to load built-in modules +in a globally available function. ES Modules that need to support +other environments can use it to conditionally load a Node.js built-in +when it is run in Node.js, without having to deal with the resolution +error that can be thrown by `import` in a non-Node.js environment or +having to use dynamic `import()` which either turns the module into +an asynchronous module, or turns a synchronous API into an asynchronous one. + +```mjs +if (globalThis.process?.getBuiltinModule) { + // Run in Node.js, use the Node.js fs module. + const fs = globalThis.process.getBuiltinModule('fs'); + // If `require()` is needed to load user-modules, use createRequire() + const module = globalThis.process.getBuiltinModule('module'); + const require = module.createRequire(import.meta.url); + const foo = require('foo'); +} +``` + +If `id` specifies a built-in module available in the current Node.js process, +`process.getBuiltinModule(id)` method returns the corresponding built-in +module. If `id` does not correspond to any built-in module, `undefined` +is returned. + +`process.getBuiltinModule(id)` accepts built-in module IDs that are recognized +by [`module.isBuiltin(id)`][]. Some built-in modules must be loaded with the +`node:` prefix, see [built-in modules with mandatory `node:` prefix][]. +The references returned by `process.getBuiltinModule(id)` always point to +the built-in module corresponding to `id` even if users modify +[`require.cache`][] so that `require(id)` returns something else. + ## `process.getegid()`