Skip to content

Commit a806bee

Browse files
committed
module: add prefix-only modules to module.builtinModules
Fixes #42785
1 parent 549037f commit a806bee

File tree

8 files changed

+34
-21
lines changed

8 files changed

+34
-21
lines changed

doc/api/module.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ added:
2828
A list of the names of all modules provided by Node.js. Can be used to verify
2929
if a module is maintained by a third party or not.
3030

31-
Note: the list doesn't contain [prefix-only modules][] like `node:test`.
31+
Note: the list also contains [prefix-only modules][] like `node:test`.
3232

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

doc/api/modules.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ Some built-in modules are always preferentially loaded if their identifier is
513513
passed to `require()`. For instance, `require('http')` will always
514514
return the built-in HTTP module, even if there is a file by that name. The list
515515
of built-in modules that can be loaded without using the `node:` prefix is exposed
516-
as [`module.builtinModules`][].
516+
in [`module.builtinModules`][], listed without the prefix.
517517

518518
### Built-in modules with mandatory `node:` prefix
519519

@@ -527,6 +527,8 @@ taken the name. Currently the built-in modules that requires the `node:` prefix
527527
* [`node:test`][]
528528
* [`node:test/reporters`][]
529529

530+
The list of these modules is exposed in [`module.builtinModules`][], including the prefix.
531+
530532
## Cycles
531533

532534
<!--type=misc-->

lib/internal/bootstrap/realm.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -320,14 +320,17 @@ class BuiltinModule {
320320
);
321321
}
322322

323-
static getCanBeRequiredByUsersWithoutSchemeList() {
324-
return ArrayFrom(canBeRequiredByUsersWithoutSchemeList);
325-
}
326-
327323
static getSchemeOnlyModuleNames() {
328324
return ArrayFrom(schemelessBlockList);
329325
}
330326

327+
static getAllBuiltinModuleIds() {
328+
return [
329+
...canBeRequiredByUsersWithoutSchemeList,
330+
...ArrayFrom(schemelessBlockList, (x) => `node:${x}`),
331+
];
332+
}
333+
331334
// Used by user-land module loaders to compile and load builtins.
332335
compileForPublicLoader() {
333336
if (!BuiltinModule.canBeRequiredByUsers(this.id)) {

lib/internal/modules/cjs/loader.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,8 +434,8 @@ Module.isBuiltin = BuiltinModule.isBuiltin;
434434
*/
435435
function initializeCJS() {
436436
// This need to be done at runtime in case --expose-internals is set.
437-
const builtinModules = BuiltinModule.getCanBeRequiredByUsersWithoutSchemeList();
438-
Module.builtinModules = ObjectFreeze(builtinModules);
437+
438+
Module.builtinModules = ObjectFreeze(BuiltinModule.getAllBuiltinModuleIds());
439439

440440
initializeCjsConditions();
441441

test/parallel/test-internal-module-require.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ if (process.argv[2] === 'child') {
8787
});
8888
} else {
8989
require(id);
90+
if (!id.startsWith('node:')) {
91+
require(`node:${id}`);
92+
}
9093
publicModules.add(id);
9194
}
9295
}

test/parallel/test-process-get-builtin.mjs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ for (const id of publicBuiltins) {
4949
const ids = publicBuiltins.add('test');
5050
// Check that import(id).default returns the same thing as process.getBuiltinModule(id).
5151
for (const id of ids) {
52-
const prefixed = `node:${id}`;
53-
const imported = await import(prefixed);
54-
assert.strictEqual(process.getBuiltinModule(prefixed), imported.default);
52+
if (!id.startsWith('node:')) {
53+
const prefixed = `node:${id}`;
54+
const imported = await import(prefixed);
55+
assert.strictEqual(process.getBuiltinModule(prefixed), imported.default);
56+
}
5557
}

test/parallel/test-repl-tab-complete-import.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,12 @@ testMe._domain.on('error', assert.ifError);
3232
testMe.complete('import(\'', common.mustCall((error, data) => {
3333
assert.strictEqual(error, null);
3434
publicModules.forEach((lib) => {
35-
assert(
36-
data[0].includes(lib) && data[0].includes(`node:${lib}`),
37-
`${lib} not found`,
38-
);
35+
if (!lib.startsWith('node:')) {
36+
assert(
37+
data[0].includes(lib) && data[0].includes(`node:${lib}`),
38+
`${lib} not found`,
39+
);
40+
}
3941
});
4042
const newModule = 'foobar';
4143
assert(!builtinModules.includes(newModule));
@@ -56,8 +58,10 @@ testMe.complete("import\t( 'n", common.mustCall((error, data) => {
5658
let lastIndex = -1;
5759

5860
publicModules.forEach((lib, index) => {
59-
lastIndex = completions.indexOf(`node:${lib}`);
60-
assert.notStrictEqual(lastIndex, -1);
61+
if (!lib.startsWith('node:')) {
62+
lastIndex = completions.indexOf(`node:${lib}`);
63+
assert.notStrictEqual(lastIndex, -1);
64+
}
6165
});
6266
assert.strictEqual(completions[lastIndex + 1], '');
6367
// There is only one Node.js module that starts with n:

test/parallel/test-require-resolve.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,9 @@ require(fixtures.path('resolve-paths', 'default', 'verify-paths.js'));
6161
// builtinModules.
6262
builtinModules.forEach((mod) => {
6363
assert.strictEqual(require.resolve.paths(mod), null);
64-
});
65-
66-
builtinModules.forEach((mod) => {
67-
assert.strictEqual(require.resolve.paths(`node:${mod}`), null);
64+
if (!mod.startsWith('node:')) {
65+
assert.strictEqual(require.resolve.paths(`node:${mod}`), null);
66+
}
6867
});
6968

7069
// node_modules.

0 commit comments

Comments
 (0)