module: add prefix-only modules to `module.builtinModules` · nodejs/node@b5a2c07

10 files changed

lines changed

Original file line numberDiff line numberDiff line change

@@ -21,15 +21,17 @@ added:

2121

- v9.3.0

2222

- v8.10.0

2323

- v6.13.0

24+

changes:

25+

- version: REPLACEME

26+

pr-url: https://github.com/nodejs/node/pull/56185

27+

description: The list now also contains prefix-only modules.

2428

-->

2529
2630

* {string\[]}

2731
2832

A list of the names of all modules provided by Node.js. Can be used to verify

2933

if a module is maintained by a third party or not.

3034
31-

Note: the list doesn't contain [prefix-only modules][] like `node:test`.

32-
3335

`module` in this context isn't the same object that's provided

3436

by the [module wrapper][]. To access it, require the `Module` module:

3537

@@ -1723,7 +1725,6 @@ returned object contains the following keys:

17231725

[load hook]: #loadurl-context-nextload

17241726

[module compile cache]: #module-compile-cache

17251727

[module wrapper]: modules.md#the-module-wrapper

1726-

[prefix-only modules]: modules.md#built-in-modules-with-mandatory-node-prefix

17271728

[realm]: https://tc39.es/ecma262/#realm

17281729

[resolve hook]: #resolvespecifier-context-nextresolve

17291730

[source map include directives]: https://sourcemaps.info/spec.html#h.lmz475t4mvbx

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-->

Original file line numberDiff line numberDiff line change

@@ -54,6 +54,7 @@ const {

5454

ArrayPrototypeIncludes,

5555

ArrayPrototypeMap,

5656

ArrayPrototypePush,

57+

ArrayPrototypePushApply,

5758

ArrayPrototypeSlice,

5859

Error,

5960

ObjectDefineProperty,

@@ -320,14 +321,16 @@ class BuiltinModule {

320321

);

321322

}

322323
323-

static getCanBeRequiredByUsersWithoutSchemeList() {

324-

return ArrayFrom(canBeRequiredByUsersWithoutSchemeList);

325-

}

326-
327324

static getSchemeOnlyModuleNames() {

328325

return ArrayFrom(schemelessBlockList);

329326

}

330327
328+

static getAllBuiltinModuleIds() {

329+

const allBuiltins = ArrayFrom(canBeRequiredByUsersWithoutSchemeList);

330+

ArrayPrototypePushApply(allBuiltins, ArrayFrom(schemelessBlockList, (x) => `node:${x}`));

331+

return allBuiltins;

332+

}

333+
331334

// Used by user-land module loaders to compile and load builtins.

332335

compileForPublicLoader() {

333336

if (!BuiltinModule.canBeRequiredByUsers(this.id)) {

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
Original file line numberDiff line numberDiff line change

@@ -130,7 +130,7 @@ const { shouldColorize } = require('internal/util/colors');

130130

const CJSModule = require('internal/modules/cjs/loader').Module;

131131

let _builtinLibs = ArrayPrototypeFilter(

132132

CJSModule.builtinModules,

133-

(e) => e[0] !== '_',

133+

(e) => e[0] !== '_' && !StringPrototypeStartsWith(e, 'node:'),

134134

);

135135

const nodeSchemeBuiltinLibs = ArrayPrototypeMap(

136136

_builtinLibs, (lib) => `node:${lib}`);

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

}

Original file line numberDiff line numberDiff line change

@@ -41,15 +41,19 @@ for (const id of publicBuiltins) {

4141

}

4242

// Check that import(id).default returns the same thing as process.getBuiltinModule(id).

4343

for (const id of publicBuiltins) {

44-

const imported = await import(`node:${id}`);

45-

assert.strictEqual(process.getBuiltinModule(id), imported.default);

44+

if (!id.startsWith('node:')) {

45+

const imported = await import(`node:${id}`);

46+

assert.strictEqual(process.getBuiltinModule(id), imported.default);

47+

}

4648

}

4749
4850

// publicBuiltins does not include 'test' which requires the node: prefix.

4951

const ids = publicBuiltins.add('test');

5052

// Check that import(id).default returns the same thing as process.getBuiltinModule(id).

5153

for (const id of ids) {

52-

const prefixed = `node:${id}`;

53-

const imported = await import(prefixed);

54-

assert.strictEqual(process.getBuiltinModule(prefixed), imported.default);

54+

if (!id.startsWith('node:')) {

55+

const prefixed = `node:${id}`;

56+

const imported = await import(prefixed);

57+

assert.strictEqual(process.getBuiltinModule(prefixed), imported.default);

58+

}

5559

}

Original file line numberDiff line numberDiff line change

@@ -5,7 +5,7 @@ const ArrayStream = require('../common/arraystream');

55

const fixtures = require('../common/fixtures');

66

const assert = require('assert');

77

const { builtinModules } = require('module');

8-

const publicModules = builtinModules.filter((lib) => !lib.startsWith('_'));

8+

const publicUnprefixedModules = builtinModules.filter((lib) => !lib.startsWith('_') && !lib.startsWith('node:'));

99
1010

if (!common.isMainThread)

1111

common.skip('process.chdir is not available in Workers');

@@ -31,7 +31,7 @@ testMe._domain.on('error', assert.ifError);

3131

// Tab complete provides built in libs for import()

3232

testMe.complete('import(\'', common.mustCall((error, data) => {

3333

assert.strictEqual(error, null);

34-

publicModules.forEach((lib) => {

34+

publicUnprefixedModules.forEach((lib) => {

3535

assert(

3636

data[0].includes(lib) && data[0].includes(`node:${lib}`),

3737

`${lib} not found`,

@@ -55,7 +55,7 @@ testMe.complete("import\t( 'n", common.mustCall((error, data) => {

5555

// import(...) completions include `node:` URL modules:

5656

let lastIndex = -1;

5757
58-

publicModules.forEach((lib, index) => {

58+

publicUnprefixedModules.forEach((lib, index) => {

5959

lastIndex = completions.indexOf(`node:${lib}`);

6060

assert.notStrictEqual(lastIndex, -1);

6161

});

Original file line numberDiff line numberDiff line change

@@ -275,7 +275,7 @@ testMe.complete('require(\'', common.mustCall(function(error, data) {

275275

assert.strictEqual(error, null);

276276

publicModules.forEach((lib) => {

277277

assert(

278-

data[0].includes(lib) && data[0].includes(`node:${lib}`),

278+

data[0].includes(lib) && (lib.startsWith('node:') || data[0].includes(`node:${lib}`)),

279279

`${lib} not found`

280280

);

281281

});

@@ -295,7 +295,7 @@ testMe.complete("require\t( 'n", common.mustCall(function(error, data) {

295295

// require(...) completions include `node:`-prefixed modules:

296296

let lastIndex = -1;

297297
298-

publicModules.forEach((lib, index) => {

298+

publicModules.filter((lib) => !lib.startsWith('node:')).forEach((lib, index) => {

299299

lastIndex = data[0].indexOf(`node:${lib}`);

300300

assert.notStrictEqual(lastIndex, -1);

301301

});

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.