Skip to content

Commit

Permalink
module: add module.builtinPrefixOnlyModules
Browse files Browse the repository at this point in the history
Fixes #42785
  • Loading branch information
ljharb committed Dec 8, 2024
1 parent dbfcbe3 commit 60f1b3a
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 3 deletions.
27 changes: 27 additions & 0 deletions doc/api/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,33 @@ import { builtinModules as builtin } from 'node:module';
const builtin = require('node:module').builtinModules;
```

### `module.builtinPrefixOnlyModules`

<!-- YAML
added:
- ?.?.?
-->

* {string\[]}

A list of the names of all modules provided by Node.js that require a `node:` prefix.
Can be used to verify if a module is maintained by a third party or not.

`module` in this context isn't the same object that's provided
by the [module wrapper][]. To access it, require the `Module` module:

```mjs
// module.mjs
// In an ECMAScript module
import { builtinPrefoxOnlyModules as builtinPrefixOnly } from 'node:module';
```

```cjs
// module.cjs
// In a CommonJS module
const builtinPrefixOnly = require('node:module').builtinPrefoxOnlyModules;
```

### `module.createRequire(filename)`

<!-- YAML
Expand Down
3 changes: 3 additions & 0 deletions doc/api/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,8 @@ taken the name. Currently the built-in modules that requires the `node:` prefix
* [`node:test`][]
* [`node:test/reporters`][]

The list of these modules is exposed as [`module.builtinPrefixOnlyModules`][].

## Cycles

<!--type=misc-->
Expand Down Expand Up @@ -1278,6 +1280,7 @@ This section was moved to
[`__filename`]: #__filename
[`import()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import
[`module.builtinModules`]: module.md#modulebuiltinmodules
[`module.builtinPrefixOnlyModules`]: module.md#modulebuiltinprefixonlymodules
[`module.children`]: #modulechildren
[`module.id`]: #moduleid
[`module` core module]: module.md
Expand Down
3 changes: 3 additions & 0 deletions lib/internal/modules/cjs/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,9 @@ function initializeCJS() {
const builtinModules = BuiltinModule.getCanBeRequiredByUsersWithoutSchemeList();
Module.builtinModules = ObjectFreeze(builtinModules);

const builtinPrefixOnlyModules = ArrayPrototypeMap(BuiltinModule.getSchemeOnlyModuleNames(), x => `node:${x}`);
Module.builtinPrefixOnlyModules = ObjectFreeze(builtinPrefixOnlyModules);

initializeCjsConditions();

if (!getEmbedderOptions().noGlobalSearchPaths) {
Expand Down
14 changes: 11 additions & 3 deletions test/parallel/test-internal-module-require.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const expectedPublicModules = new Set([

if (process.argv[2] === 'child') {
assert(!process.execArgv.includes('--expose-internals'));
process.once('message', ({ allBuiltins }) => {
process.once('message', ({ allBuiltins, builtinPrefixOnlyModules }) => {
const publicModules = new Set();
for (const id of allBuiltins) {
if (id.startsWith('internal/')) {
Expand All @@ -88,6 +88,7 @@ if (process.argv[2] === 'child') {
} else {
require(id);
publicModules.add(id);
require(`node:${id}`);
}
}
assert(allBuiltins.length > publicModules.size);
Expand All @@ -98,15 +99,22 @@ if (process.argv[2] === 'child') {
new Set(require('module').builtinModules)
);
assert.deepStrictEqual(publicModules, expectedPublicModules);

const prefixOnlyModules = new Set();
for (const id of builtinPrefixOnlyModules) {
require(id);
prefixOnlyModules.add(id);
}
assert.deepStrictEqual(prefixOnlyModules, new Set(require('module').builtinPrefixOnlyModules));
});
} else {
assert(process.execArgv.includes('--expose-internals'));
const child = fork(__filename, ['child'], {
execArgv: []
});
const { builtinModules } = require('module');
const { builtinModules, builtinPrefixOnlyModules } = require('module');
// When --expose-internals is on, require('module').builtinModules
// contains internal modules.
const message = { allBuiltins: builtinModules };
const message = { allBuiltins: builtinModules, builtinPrefixOnlyModules };
child.send(message);
}

0 comments on commit 60f1b3a

Please sign in to comment.