Skip to content

Commit 8c31f00

Browse files
committed
vfs: allow imports without the node: prefix
The experimental VFS module previously required the node: prefix. Allow both vfs and node:vfs in CommonJS and ESM while keeping --experimental-vfs gating unchanged. Assisted-by: Pi Signed-off-by: Matteo Collina <hello@matteocollina.com>
1 parent ebef774 commit 8c31f00

3 files changed

Lines changed: 45 additions & 28 deletions

File tree

‎lib/internal/bootstrap/realm.js‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@ const schemelessBlockList = new SafeSet([
133133
'quic',
134134
'test',
135135
'test/reporters',
136-
'vfs',
137136
]);
138137
// Modules that will only be enabled at run time.
139138
const experimentalModuleList = new SafeSet([

‎test/parallel/test-module-builtin-experimental.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ const experimentalBuiltins = [
88
['bench/reporters', '--experimental-bench', true],
99
['dtls', '--experimental-dtls', common.hasDtls],
1010
['quic', '--experimental-quic', common.hasQuic],
11-
['vfs', '--experimental-vfs', true],
1211
].filter(([, , available]) => available);
1312

1413
for (const [id, flag] of experimentalBuiltins) {
@@ -25,6 +24,7 @@ for (const [id, flag] of experimentalBuiltins) {
2524
}
2625

2726
const schemelessExperimentalBuiltins = [
27+
['vfs', '--experimental-vfs'],
2828
['stream/iter', '--experimental-stream-iter'],
2929
['zlib/iter', '--experimental-stream-iter'],
3030
];

‎test/parallel/test-vfs-flag.js‎

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,45 @@
11
'use strict';
22

3-
// node:vfs is gated behind --experimental-vfs. Without the flag the
4-
// module is not exposed; bare `vfs` (without the node: scheme) is also
5-
// blocked.
3+
// Both vfs and node:vfs are gated behind --experimental-vfs.
64

75
require('../common');
86
const { spawnSyncAndAssert } = require('../common/child_process');
97

10-
// Without the flag, requiring node:vfs throws ERR_UNKNOWN_BUILTIN_MODULE.
11-
{
12-
spawnSyncAndAssert(process.execPath, [
13-
'-e', 'require("node:vfs")',
14-
], { status: 1, stderr: /ERR_UNKNOWN_BUILTIN_MODULE/ });
15-
}
8+
// Without the flag, or when explicitly disabled, neither specifier is exposed.
9+
for (const flags of [[], ['--no-experimental-vfs']]) {
10+
for (const [id, requireError, importError] of [
11+
['vfs', 'MODULE_NOT_FOUND', 'ERR_MODULE_NOT_FOUND'],
12+
['node:vfs', 'ERR_UNKNOWN_BUILTIN_MODULE', 'ERR_UNKNOWN_BUILTIN_MODULE'],
13+
]) {
14+
spawnSyncAndAssert(process.execPath, [
15+
...flags,
16+
'-e',
17+
`const assert = require('node:assert');
18+
const { isBuiltin } = require('node:module');
19+
assert.strictEqual(isBuiltin('${id}'), false);
20+
assert.strictEqual(process.getBuiltinModule('${id}'), undefined);
21+
assert.throws(() => require('${id}'), { code: '${requireError}' });`,
22+
], { status: 0 });
1623

17-
// Without the flag, importing node:vfs throws ERR_UNKNOWN_BUILTIN_MODULE.
18-
{
19-
spawnSyncAndAssert(process.execPath, [
20-
'--input-type=module',
21-
'-e', 'import("node:vfs").catch((e) => { console.error(e.code); process.exit(1); });',
22-
], {
23-
status: 1,
24-
stderr: /ERR_UNKNOWN_BUILTIN_MODULE/,
25-
});
24+
spawnSyncAndAssert(process.execPath, [
25+
...flags,
26+
'--input-type=module',
27+
'-e',
28+
`import assert from 'node:assert';
29+
await assert.rejects(import('${id}'), { code: '${importError}' });`,
30+
], { status: 0 });
31+
}
2632
}
2733

28-
// With the flag, node:vfs loads and works.
29-
{
34+
// With the flag, both specifiers resolve to the same CommonJS exports.
35+
for (const id of ['vfs', 'node:vfs']) {
3036
const script =
31-
'const v = require("node:vfs");' +
37+
'const assert = require("node:assert");' +
38+
`const v = require('${id}');` +
39+
'assert.strictEqual(v, require("node:vfs"));' +
40+
`assert.strictEqual(require.resolve('${id}'), '${id}');` +
41+
`assert.strictEqual(require('node:module').isBuiltin('${id}'), true);` +
42+
`assert.strictEqual(process.getBuiltinModule('${id}'), v);` +
3243
'const x = v.create();' +
3344
'x.writeFileSync("/x", "hi");' +
3445
'console.log(x.readFileSync("/x", "utf8"));';
@@ -38,22 +49,29 @@ const { spawnSyncAndAssert } = require('../common/child_process');
3849
});
3950
}
4051

41-
// Bare `vfs` (no node: scheme) is always blocked.
52+
// Static and dynamic ESM imports share the same module and named exports.
4253
{
4354
spawnSyncAndAssert(process.execPath, [
4455
'--experimental-vfs',
45-
'-e', "require('vfs')",
46-
], { status: 1, stderr: /Cannot find module 'vfs'/ });
56+
'--input-type=module',
57+
'-e',
58+
`import assert from 'node:assert';
59+
import vfs, { create } from 'vfs';
60+
import nodeVfs, { create as nodeCreate } from 'node:vfs';
61+
assert.strictEqual(vfs, nodeVfs);
62+
assert.strictEqual(create, nodeCreate);
63+
assert.strictEqual(await import('vfs'), await import('node:vfs'));`,
64+
], { status: 0 });
4765
}
4866

49-
// Module.builtinModules reflects whether --experimental-vfs is active.
67+
// Module.builtinModules lists the bare name when --experimental-vfs is active.
5068
for (const [flag, expected] of [
5169
['--experimental-vfs', 'true\n'],
5270
['--no-experimental-vfs', 'false\n'],
5371
]) {
5472
spawnSyncAndAssert(process.execPath, [
5573
flag,
5674
'-p',
57-
'require("node:module").builtinModules.includes("node:vfs")',
75+
'require("node:module").builtinModules.includes("vfs")',
5876
], { stdout: expected, stderr: '' });
5977
}

0 commit comments

Comments
 (0)