vfs: unflag

Enable node:vfs by default. --no-experimental-vfs disables node:vfs
exposure and --vfs-load.

Assisted-by: pi
Signed-off-by: Matteo Collina <hello@matteocollina.com>
PR-URL: https://github.com/nodejs/node/pull/66318
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
This commit is contained in:
Matteo Collina authored and GitHub committed 2026-10-15 07:53:03 +00:00
1 parent f0f8115e10
commit 49ad95045a
134 files changed
+248 -228

No files matched your search

+23 -21
View File
@@ -330,7 +330,7 @@ so mounting one is gated on its own flag rather than on `--allow-fs-read` or
`--allow-fs-write`.
```console
$ node --experimental-vfs --permission --allow-fs-vfs app.js
$ node --permission --allow-fs-vfs app.js
```
### `--allow-fs-write`
@@ -1711,16 +1711,6 @@ with AND, so a test must satisfy every expression to run.
A malformed expression causes the test runner to exit with a non-zero status
before running any tests.
### `--experimental-vfs`
<!-- YAML
added: v26.4.0
-->
> Stability: 1 - Experimental
Enable the experimental [`node:vfs`][] module.
### `--experimental-vm-modules`
<!-- YAML
@@ -2364,6 +2354,18 @@ changes:
Disable the experimental [`node:sqlite`][] module.
### `--no-experimental-vfs`
<!-- YAML
added: v26.4.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/66318
description: VFS is unflagged but still experimental.
-->
Disable the experimental [`node:vfs`][] module and `--vfs-load`.
### `--no-experimental-webstorage`
<!-- YAML
@@ -3907,11 +3909,13 @@ added: v26.10.0
* `source` {string} A directory or an archive file to mount and run.
Requires [`--experimental-vfs`][]. May be given at most once.
May be given at most once.
Mounts `source` as a virtual file system ([`node:vfs`][]), and runs the entry
point and all subsequent `require()`/`import` resolution against that mount
rather than the real file system. The mount is placed at a reserved mount point
rather than the real file system. This option is unavailable when
`--no-experimental-vfs` disables [`node:vfs`][]. The mount is placed at a
reserved mount point
assigned by Node.js, so it never shadows real paths and no target can be
chosen. The entry point is taken from the mount the same way `node <directory>`
takes one: the mount's own `package.json` `"main"`, or `index.js`. Any
@@ -3942,18 +3946,17 @@ same thing in all of them.
A worker created with its own `execArgv` inherits none of the parent's options,
and so does not mount the source at all. To run a script from the mount, such a
worker must be given the same options again, `--experimental-vfs` and
`--vfs-load`; without them, that thread has no mount for the script to come
from, and the worker fails to load it. `--experimental-vfs` is also what makes
[`node:vfs`][] available to the worker's own code. A worker whose script comes
from anywhere else, such as the real file system, needs nothing added.
worker must be given `--vfs-load` again; without it, that thread has no mount
for the script to come from, and the worker fails to load it. [`node:vfs`][] is
available to worker code without an experimental flag. A worker whose script
comes from anywhere else, such as the real file system, needs nothing added.
`--vfs-load` is not permitted in [`NODE_OPTIONS`][]: which entry point runs is
the command line's decision, and the environment must not be able to redirect
it.
```console
$ node --experimental-vfs --vfs-load=app.zip
$ node --vfs-load=app.zip
```
### `--watch`
@@ -4280,7 +4283,6 @@ one is included in the list below.
* `--experimental-stream-iter`
* `--experimental-test-isolation`
* `--experimental-top-level-await`
* `--experimental-vfs`
* `--experimental-vm-modules`
* `--experimental-wasi-unstable-preview1`
* `--experimental-web-worker`
@@ -4315,6 +4317,7 @@ one is included in the list below.
* `--no-experimental-global-navigator`
* `--no-experimental-sqlite`
* `--no-experimental-strip-types`
* `--no-experimental-vfs`
* `--no-experimental-webstorage`
* `--no-extra-info-on-fatal-exception`
* `--no-force-async-hooks-checks`
@@ -4914,7 +4917,6 @@ node --stack-trace-limit=12 -p -e "Error.stackTraceLimit" # prints 12
[`--env-file-if-exists`]: #--env-file-if-existsfile
[`--env-file`]: #--env-filefile
[`--experimental-sea-config`]: single-executable-applications.md#1-generating-single-executable-preparation-blobs
[`--experimental-vfs`]: #--experimental-vfs
[`--heap-prof-dir`]: #--heap-prof-dir
[`--import`]: #--importmodule
[`--no-require-module`]: #--no-require-module
+9 -7
View File
@@ -24,8 +24,8 @@ import vfs from 'node:vfs';
const vfs = require('node:vfs');
```
This module is only available under the `node:` scheme, and only when Node.js
is started with the `--experimental-vfs` flag.
This module is only available under the `node:` scheme. Loading it emits an
`ExperimentalWarning`.
## Security
@@ -77,8 +77,9 @@ added: v26.4.0
* `provider` {VirtualProvider} The provider to use. **Default:**
`new MemoryProvider()`.
* `options` {Object}
* `emitExperimentalWarning` {boolean} Whether to emit the experimental
warning when the instance is created. **Default:** `true`.
* `emitExperimentalWarning` {boolean} Whether to emit an experimental warning
when an instance is created. **Default:** `true`. Loading `node:vfs` emits
the warning regardless of this option.
* Returns: {VirtualFileSystem}
Convenience factory equivalent to `new VirtualFileSystem(provider, options)`.
@@ -148,7 +149,7 @@ vfs.registerProvider({
```
```console
$ node --experimental-vfs --require ./provider.js \
$ node --require ./provider.js \
--vfs-load archive.customfmt
```
@@ -193,8 +194,9 @@ added: v26.4.0
* `provider` {VirtualProvider} The provider to use. **Default:**
`new MemoryProvider()`.
* `options` {Object}
* `emitExperimentalWarning` {boolean} Whether to emit the experimental
warning. **Default:** `true`.
* `emitExperimentalWarning` {boolean} Whether to emit an experimental warning
when an instance is created. **Default:** `true`. Loading `node:vfs` emits
the warning regardless of this option.
### `vfs.mount()`
+15 -14
View File
@@ -210,7 +210,7 @@ A mounted VFS serves paths that the file system permissions do not describe,
so mounting one is gated on its own flag rather than on \fB--allow-fs-read\fR or
\fB--allow-fs-write\fR.
.Bd -literal
$ node --experimental-vfs --permission --allow-fs-vfs app.js
$ node --permission --allow-fs-vfs app.js
.Ed
.
.It Fl -allow-fs-write
@@ -930,9 +930,6 @@ with AND, so a test must satisfy every expression to run.
A malformed expression causes the test runner to exit with a non-zero status
before running any tests.
.
.It Fl -experimental-vfs
Enable the experimental \fBnode:vfs\fR module.
.
.It Fl -experimental-vm-modules
Enable experimental ES Module support in the \fBnode:vm\fR module.
.
@@ -1233,6 +1230,9 @@ Legacy alias for \fB--no-require-module\fR.
.It Fl -no-experimental-sqlite
Disable the experimental \fBnode:sqlite\fR module.
.
.It Fl -no-experimental-vfs
Disable the experimental \fBnode:vfs\fR module and \fB--vfs-load\fR.
.
.It Fl -no-experimental-webstorage
Disable \fBWeb Storage\fR support.
.
@@ -1973,10 +1973,12 @@ Print node's version.
.It
\fBsource\fR \fB{string}\fR A directory or an archive file to mount and run.
.El
Requires \fB--experimental-vfs\fR. May be given at most once.
May be given at most once.
Mounts \fBsource\fR as a virtual file system (\fBnode:vfs\fR), and runs the entry
point and all subsequent \fBrequire()\fR/\fBimport\fR resolution against that mount
rather than the real file system. The mount is placed at a reserved mount point
rather than the real file system. This option is unavailable when
\fB--no-experimental-vfs\fR disables \fBnode:vfs\fR. The mount is placed at a
reserved mount point
assigned by Node.js, so it never shadows real paths and no target can be
chosen. The entry point is taken from the mount the same way \fBnode <directory>\fR
takes one: the mount's own \fBpackage.json\fR \fB"main"\fR, or \fBindex.js\fR. Any
@@ -2004,16 +2006,15 @@ mounts it, whatever else that thread mounts, so a path into the mount means the
same thing in all of them.
A worker created with its own \fBexecArgv\fR inherits none of the parent's options,
and so does not mount the source at all. To run a script from the mount, such a
worker must be given the same options again, \fB--experimental-vfs\fR and
\fB--vfs-load\fR; without them, that thread has no mount for the script to come
from, and the worker fails to load it. \fB--experimental-vfs\fR is also what makes
\fBnode:vfs\fR available to the worker's own code. A worker whose script comes
from anywhere else, such as the real file system, needs nothing added.
worker must be given \fB--vfs-load\fR again; without it, that thread has no mount
for the script to come from, and the worker fails to load it. \fBnode:vfs\fR is
available to worker code without an experimental flag. A worker whose script
comes from anywhere else, such as the real file system, needs nothing added.
\fB--vfs-load\fR is not permitted in \fBNODE_OPTIONS\fR: which entry point runs is
the command line's decision, and the environment must not be able to redirect
it.
.Bd -literal
$ node --experimental-vfs --vfs-load=app.zip
$ node --vfs-load=app.zip
.Ed
.
.It Fl -watch
@@ -2271,8 +2272,6 @@ one is included in the list below.
.It
\fB--experimental-top-level-await\fR
.It
\fB--experimental-vfs\fR
.It
\fB--experimental-vm-modules\fR
.It
\fB--experimental-wasi-unstable-preview1\fR
@@ -2341,6 +2340,8 @@ one is included in the list below.
.It
\fB--no-experimental-strip-types\fR
.It
\fB--no-experimental-vfs\fR
.It
\fB--no-experimental-webstorage\fR
.It
\fB--no-extra-info-on-fatal-exception\fR
+1 -2
View File
@@ -15,7 +15,6 @@ const {
ERR_INVALID_STATE,
},
} = require('internal/errors');
const { validateBoolean } = require('internal/validators');
const { MemoryProvider } = require('internal/vfs/providers/memory');
const path = require('path');
const { posix: pathPosix, resolve: resolvePath, sep, toNamespacedPath } = path;
@@ -39,6 +38,7 @@ const {
const { VirtualReadStream, VirtualWriteStream } = require('internal/vfs/streams');
const { VirtualDir } = require('internal/vfs/dir');
const { emitExperimentalWarning, kEmptyObject } = require('internal/util');
const { validateBoolean } = require('internal/validators');
let debug = require('internal/util/debuglog').debuglog('vfs', (fn) => {
debug = fn;
});
@@ -111,7 +111,6 @@ class VirtualFileSystem {
/**
* @param {VirtualProvider|object} [providerOrOptions] The provider to use, or options
* @param {object} [options] Configuration options
* @param {boolean} [options.emitExperimentalWarning] Emit the experimental warning (default: true)
*/
constructor(providerOrOptions, options = kEmptyObject) {
let provider = null;
+3
View File
@@ -4,6 +4,9 @@ const {
FunctionPrototypeSymbolHasInstance,
} = primordials;
const { emitExperimentalWarning } = require('internal/util');
emitExperimentalWarning('VirtualFileSystem');
const { VirtualFileSystem } = require('internal/vfs/file_system');
const { VirtualProvider } = require('internal/vfs/provider');
const { MemoryProvider } = require('internal/vfs/providers/memory');
+1 -1
View File
@@ -1119,7 +1119,7 @@ static ExitCode InitializeNodeWithArgsInternal(
{
auto* env_options = per_process::cli_options->per_isolate->per_env.get();
if (!env_options->experimental_vfs && env_options->vfs_load) {
errors->push_back("--vfs-load requires --experimental-vfs");
errors->push_back("--vfs-load requires node:vfs to be enabled");
}
// A second --vfs-load would silently replace the first, and the option
// itself cannot say how often it was given; count it in the node options
+3 -2
View File
@@ -801,7 +801,8 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
AddOption("--experimental-vfs",
"experimental node:vfs module",
BOOL_FIELD(experimental_vfs),
kAllowedInEnvvar);
kAllowedInEnvvar,
true);
// Choosing the entry point is the command line's alone: an environment
// variable must not be able to redirect what a `node <args>` invocation runs,
// so this is rejected in NODE_OPTIONS. The source and whether to run from it
@@ -810,7 +811,7 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
AddOption("--vfs-load",
"mount a directory or archive as a virtual file system and run the "
"entry point and module resolution against it instead of the real "
"file system (may be given once; requires --experimental-vfs)",
"file system (may be given once)",
&EnvironmentOptions::vfs_load_source,
kDisallowedInEnvvar);
AddOption("[vfs_load_set]", "", BOOL_FIELD(vfs_load));
+1 -1
View File
@@ -215,7 +215,7 @@ class EnvironmentOptions : public Options {
DEFINE_BOOL_FIELD(experimental_websocket) = true;
DEFINE_BOOL_FIELD(experimental_sqlite) = HAVE_SQLITE;
DEFINE_BOOL_FIELD(experimental_stream_iter) = EXPERIMENTALS_DEFAULT_VALUE;
DEFINE_BOOL_FIELD(experimental_vfs) = EXPERIMENTALS_DEFAULT_VALUE;
DEFINE_BOOL_FIELD(experimental_vfs) = true;
DEFINE_BOOL_FIELD(vfs_load) = false;
DEFINE_BOOL_FIELD(webstorage) = HAVE_SQLITE;
DEFINE_BOOL_FIELD(experimental_dtls) = EXPERIMENTALS_DEFAULT_VALUE;
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
const common = require('../common');
common.skipIfFFIMissing();
@@ -1,3 +1,4 @@
// Flags: --disable-warning=ExperimentalWarning
'use strict';
const common = require('../common');
@@ -8,7 +9,6 @@ const experimentalBuiltins = [
['bench/reporters', '--experimental-bench', true],
['dtls', '--experimental-dtls', common.hasDtls],
['quic', '--experimental-quic', common.hasQuic],
['vfs', '--experimental-vfs', true],
].filter(([, , available]) => available);
for (const [id, flag] of experimentalBuiltins) {
@@ -51,7 +51,14 @@ if (common.hasFFI) {
], { status: 0 });
}
const schemeOnlyBuiltins = ['node:test', 'node:sea'];
// node:vfs is enabled by default and can be disabled with
// --no-experimental-vfs.
spawnSyncAndAssert(process.execPath, [
'--no-experimental-vfs',
'-e', `const m = require('node:module'); if (m.builtinModules.includes('node:vfs')) process.exit(1); try { require('node:vfs'); } catch (e) { if (e.code === 'ERR_UNKNOWN_BUILTIN_MODULE') process.exit(0); } process.exit(1);`,
], { status: 0 });
const schemeOnlyBuiltins = ['node:test', 'node:sea', 'node:vfs'];
if (common.hasFFI) {
schemeOnlyBuiltins.push('node:ffi');
}
@@ -92,7 +92,7 @@ function run(...permissions) {
`;
const vfsRun = (...permissions) => spawnSync(
process.execPath,
['--experimental-vfs', '--permission', '--allow-fs-read=*',
['--permission', '--allow-fs-read=*',
...permissions, '-e', mounted],
{ encoding: 'utf8' });
-2
View File
@@ -62,8 +62,6 @@ require(fixtures.path('resolve-paths', 'default', 'verify-paths.js'));
builtinModules.forEach((mod) => {
// TODO(@jasnell): Remove once node:quic is no longer flagged
if (mod === 'node:quic') return;
// Remove once node:vfs is no longer flagged
if (mod === 'node:vfs') return;
if (mod === 'node:sqlite' && !common.hasSQLite) return;
assert.strictEqual(require.resolve.paths(mod), null);
if (!mod.startsWith('node:')) {
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// access / accessSync honour the R_OK / W_OK / X_OK / F_OK mode bits and
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
const common = require('../common');
const assert = require('assert');
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// writeSync in append mode must append, not overwrite.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// VFS readSync should accept a BigInt position parameter.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// Exercise the VFS callback-style async API on every method.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// Tests for VFS copyFile mode support:
+4 -5
View File
@@ -1,7 +1,7 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// Constructor variants and option validation for vfs.create() and
// Constructor variants for vfs.create() and
// `new VirtualFileSystem(...)`.
require('../common');
@@ -14,10 +14,9 @@ const vfs = require('node:vfs');
assert.ok(myVfs.provider instanceof vfs.MemoryProvider);
}
// vfs.create with first arg as options object (no provider)
// vfs.create with the options object as its first argument
{
const myVfs = vfs.create({ emitExperimentalWarning: false });
assert.ok(myVfs);
assert.ok(myVfs.provider instanceof vfs.MemoryProvider);
}
@@ -28,7 +27,7 @@ const vfs = require('node:vfs');
assert.strictEqual(myVfs.provider, provider);
}
// new VirtualFileSystem(options) directly
// new VirtualFileSystem() directly
{
const myVfs = new vfs.VirtualFileSystem({ emitExperimentalWarning: false });
assert.ok(myVfs);
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
require('../common');
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
const common = require('../common');
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// Exercise the VirtualDir handle returned by opendirSync.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
const common = require('../common');
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// Exercise VirtualFileHandle / MemoryFileHandle methods directly via
+36 -41
View File
@@ -1,59 +1,54 @@
'use strict';
// node:vfs is gated behind --experimental-vfs. Without the flag the
// module is not exposed; bare `vfs` (without the node: scheme) is also
// blocked.
// node:vfs is available without an experimental flag. The old positive flag
// remains accepted for compatibility, and --no-experimental-vfs disables it.
require('../common');
const { spawnSyncAndAssert } = require('../common/child_process');
// Without the flag, requiring node:vfs throws ERR_UNKNOWN_BUILTIN_MODULE.
{
spawnSyncAndAssert(process.execPath, [
'-e', 'require("node:vfs")',
], { status: 1, stderr: /ERR_UNKNOWN_BUILTIN_MODULE/ });
}
// Without the flag, importing node:vfs throws ERR_UNKNOWN_BUILTIN_MODULE.
{
spawnSyncAndAssert(process.execPath, [
'--input-type=module',
'-e', 'import("node:vfs").catch((e) => { console.error(e.code); process.exit(1); });',
], {
status: 1,
stderr: /ERR_UNKNOWN_BUILTIN_MODULE/,
});
}
// With the flag, node:vfs loads and works.
// CommonJS and ESM can load node:vfs without a flag.
{
const script =
'const v = require("node:vfs");' +
'const x = v.create();' +
'x.writeFileSync("/x", "hi");' +
'console.log(x.readFileSync("/x", "utf8"));';
spawnSyncAndAssert(process.execPath, ['--experimental-vfs', '-e', script], {
spawnSyncAndAssert(process.execPath, ['-e', script], {
stdout: 'hi',
stderr: /ExperimentalWarning: VirtualFileSystem is an experimental feature/,
trim: true,
});
spawnSyncAndAssert(process.execPath, [
'--input-type=module',
'-e', 'import("node:vfs").then(({ default: v }) => console.log(typeof v.create));',
], {
stdout: 'function\n',
stderr: /ExperimentalWarning: VirtualFileSystem is an experimental feature/,
});
}
// Bare `vfs` (no node: scheme) is always blocked.
{
spawnSyncAndAssert(process.execPath, [
'--experimental-vfs',
'-e', "require('vfs')",
], { status: 1, stderr: /Cannot find module 'vfs'/ });
}
// The old positive flag is accepted for compatibility but no longer gates the
// module.
spawnSyncAndAssert(process.execPath, [
'--experimental-vfs',
'-p',
'require("node:module").builtinModules.includes("node:vfs")',
], { stdout: 'true\n', stderr: '' });
// Module.builtinModules reflects whether --experimental-vfs is active.
for (const [flag, expected] of [
['--experimental-vfs', 'true\n'],
['--no-experimental-vfs', 'false\n'],
]) {
spawnSyncAndAssert(process.execPath, [
flag,
'-p',
'require("node:module").builtinModules.includes("node:vfs")',
], { stdout: expected, stderr: '' });
}
// --no-experimental-vfs disables node:vfs.
spawnSyncAndAssert(process.execPath, [
'--no-experimental-vfs',
'-p',
'require("node:module").builtinModules.includes("node:vfs")',
], { stdout: 'false\n', stderr: '' });
spawnSyncAndAssert(process.execPath, [
'--no-experimental-vfs',
'-e', 'require("node:vfs")',
], { status: 1, stderr: /ERR_UNKNOWN_BUILTIN_MODULE/ });
// Bare `vfs` (no node: scheme) remains unavailable.
spawnSyncAndAssert(process.execPath, [
'-e', "require('vfs')",
], { status: 1, stderr: /Cannot find module 'vfs'/ });
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.accessSync dispatches to VFS; missing paths throw ENOENT.
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// VFS dispatch on the async callback fs methods must surface provider errors
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.chmod, fs.chown, fs.lchown, fs.utimes, and fs.lutimes callbacks dispatch
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.chmodSync, fs.chownSync, fs.lchownSync, fs.utimesSync, and
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.copyFileSync dispatches to VFS when both paths are within the same mount.
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.createReadStream dispatches through VFS, including the emitted 'open'
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.createWriteStream dispatches through VFS, exposes a `path` property and
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.existsSync dispatches to VFS for paths under a mount.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.fchmod, fs.fchown, fs.futimes, fs.fdatasync, and fs.fsync callbacks
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.linkSync dispatches to VFS for hard links within the same mount.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// `node:fs` entry points route mounted paths through the VFS hooks. Where a
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.mkdir, fs.rmdir, fs.rm, and fs.unlink callbacks dispatch through VFS.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.mkdirSync dispatches to VFS, including the `recursive: true` form.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.mkdtempSync dispatches to VFS and returns a mount-rooted path, including
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.open / fs.fstat / fs.read / fs.write / fs.close / fs.ftruncate callbacks
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.openAsBlob and fs.openAsBlobSync dispatch to VFS and return Blobs over the virtual file.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.openSync / fs.readSync / fs.writeSync / fs.fstatSync / fs.closeSync /
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.opendir callback dispatches through VFS, both via readSync() iteration
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.opendirSync dispatches to VFS and returns a Dir-like iterable.
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// The promise-based fs methods that accept `encoding: 'buffer'` must convert
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fsp.stat() with throwIfNoEntry: false on a missing path within a mount
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs/promises dispatches through VFS for each supported path-based and
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.readFile, fs.readdir, fs.realpath, fs.access, and fs.exists callbacks
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.readFileSync dispatches to VFS for both string paths and VFS-owned fds.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.readdirSync dispatches to VFS, including the buffer-encoding and
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.realpathSync dispatches to VFS and returns a mount-rooted absolute path.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.rename and fs.copyFile callbacks dispatch through VFS.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.renameSync dispatches to VFS when both paths are within the same mount.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.rmSync, fs.rmdirSync, and fs.unlinkSync dispatch to VFS.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.stat and fs.lstat callbacks dispatch through VFS.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.statSync / fs.lstatSync / fs.statfsSync dispatch through the VFS layer,
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.symlink and fs.readlink callbacks dispatch through VFS.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.symlinkSync and fs.readlinkSync dispatch through VFS, including the
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.truncate, fs.link, and fs.mkdtemp callbacks dispatch through VFS.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.truncateSync dispatches to VFS and shrinks the file content.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.watch on a path under a mount returns the provider's watcher object
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.writeFile and fs.appendFile callbacks dispatch through VFS.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// fs.writeFileSync and fs.appendFileSync dispatch to VFS.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// A file handle on a mounted path must answer the same `node:fs` calls the
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// Test that nlink count is updated correctly when creating/removing hard links.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
import '../common/index.mjs';
import assert from 'assert';
import { pathToFileURL } from 'node:url';
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs --expose-internals
// Flags: --disable-warning=ExperimentalWarning --expose-internals
'use strict';
const common = require('../common');
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
// Regression: unmounting a layer whose id is a decimal prefix of another
// (e.g. layer 1 vs layer 10) must not purge the other's ESM cache entries.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
const common = require('../common');
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// Hard-link error cases: creating a link to a directory or to an
+21 -8
View File
@@ -22,7 +22,7 @@ let id = 0;
function fixture(name) { return path.join(tmpdir.path, `${id++}-${name}`); }
function run(args) {
return spawnSync(process.execPath, ['--experimental-vfs', ...args], { encoding: 'utf8' });
return spawnSync(process.execPath, args, { encoding: 'utf8' });
}
// Node.js can be built without NODE_OPTIONS support, in which case the
@@ -49,6 +49,15 @@ function envArg(flag, value) {
assert.match(res.stdout, /hello from inside the mount/);
}
// --no-experimental-vfs disables --vfs-load.
{
const dir = fixture('disabled');
fs.mkdirSync(dir, { recursive: true });
const res = run(['--no-experimental-vfs', `--vfs-load=${dir}`]);
assert.notStrictEqual(res.status, 0);
assert.match(res.stderr, /--vfs-load requires node:vfs to be enabled/);
}
// A provider registered by a -r (CommonJS) preload backs a custom file format.
{
const providerModule = fixture('provider.js');
@@ -198,7 +207,7 @@ parentPort.postMessage('hello from esm worker in mount');
const path = require('path');
const { Worker } = require('worker_threads');
const w = new Worker(path.join(__dirname, 'worker.js'), {
execArgv: ['--experimental-vfs', '--vfs-load=' + process.argv[1]],
execArgv: ['--vfs-load=' + process.argv[1]],
});
w.on('message', (m) => { console.log(m); process.exit(0); });
w.on('error', (e) => { console.error(e); process.exit(1); });
@@ -308,8 +317,7 @@ if (hasNodeOptions) {
// On its own, and alongside a --vfs-load the command line legitimately gave:
// the environment is refused either way rather than merged.
for (const args of [['--experimental-vfs'],
['--experimental-vfs', `--vfs-load=${dir}`]]) {
for (const args of [[], [`--vfs-load=${dir}`]]) {
const res = spawnSync(process.execPath, args, {
encoding: 'utf8',
env: { ...process.env, NODE_OPTIONS: envArg('--vfs-load', dir) },
@@ -319,10 +327,8 @@ if (hasNodeOptions) {
}
}
// --experimental-vfs and --vfs-load may arrive from different places: the
// options are validated once every source has been parsed, so a --vfs-load on
// the command line is not rejected for an --experimental-vfs that only
// NODE_OPTIONS carries.
// The old --experimental-vfs option remains accepted in NODE_OPTIONS. Its
// positive form no longer gates --vfs-load, and its negated form disables it.
if (hasNodeOptions) {
const dir = fixture('env-flag-cli-load');
fs.mkdirSync(dir, { recursive: true });
@@ -334,6 +340,13 @@ if (hasNodeOptions) {
});
assert.strictEqual(res.status, 0, res.stderr);
assert.match(res.stdout, /ran/);
const disabled = spawnSync(process.execPath, [`--vfs-load=${dir}`], {
encoding: 'utf8',
env: { ...process.env, NODE_OPTIONS: '--no-experimental-vfs' },
});
assert.notStrictEqual(disabled.status, 0);
assert.match(disabled.stderr, /--vfs-load requires node:vfs to be enabled/);
}
// Under --vfs-load the entry point comes from the mount, so no positional
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs --expose-internals
// Flags: --disable-warning=ExperimentalWarning --expose-internals
'use strict';
// MemoryFileHandle internals: the "stats not available" path when there
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs --expose-internals
// Flags: --disable-warning=ExperimentalWarning --expose-internals
'use strict';
// MemoryProvider supports dynamic content providers and lazily-populated
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// MemoryProvider: numeric open flags (mirroring fs.constants.O_*) must be
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs --expose-internals
// Flags: --disable-warning=ExperimentalWarning --expose-internals
'use strict';
const common = require('../common');
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// mkdirSync / rmdirSync behaviour: return value, recursive option, mode
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// mkdtemp / mkdtempSync behaviour.
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
const common = require('../common');
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
import '../common/index.mjs';
import assert from 'assert';
import { createRequire } from 'module';
+2 -2
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// The `node_modules` lookup for modules inside a mounted VFS stops at the
@@ -91,7 +91,7 @@ const tmpdir = require('../common/tmpdir');
fs.writeFileSync(path.join(globalDir, 'gdep', 'index.js'),
'module.exports = "from-node-path";');
const out = execFileSync(process.execPath, ['--experimental-vfs', '-e', `
const out = execFileSync(process.execPath, ['-e', `
const vfs = require('node:vfs');
const path = require('path');
const myVfs = vfs.create();
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs --expose-internals
// Flags: --disable-warning=ExperimentalWarning --expose-internals
'use strict';
// Error paths in the VFS mount layer:
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
require('../common');
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
const common = require('../common');
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// Two concurrent mounts must each route to its own VFS without
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// Package.json caches must be cleared on VFS unmount.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs --expose-internals
// Flags: --disable-warning=ExperimentalWarning --expose-internals
'use strict';
require('../common');
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// Operations that modify a directory should bump its mtime/ctime.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// VFS promises.open returns a usable handle.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs --expose-internals
// Flags: --disable-warning=ExperimentalWarning --expose-internals
'use strict';
const common = require('../common');
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// Recursive readdir must follow symlinks to directories.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// VFS readFile callback API.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// readFileSync with invalid encoding must throw.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
const common = require('../common');
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs --expose-internals
// Flags: --disable-warning=ExperimentalWarning --expose-internals
'use strict';
// RealFileHandle: sync and async file-handle operations, plus EBADF
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// Promises API for RealFSProvider: every async/promises method,
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// Symlink and path-escape behaviour for RealFSProvider.
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// watch / promises.watch / watchFile through RealFSProvider.
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// Synchronous API for RealFSProvider: construction, basic file ops,
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
const common = require('../common');
+1 -1
View File
@@ -1,4 +1,4 @@
// Flags: --experimental-vfs
// Flags: --disable-warning=ExperimentalWarning
'use strict';
// Rename behaviour: overwrite, type mismatches, same-parent rename.
Loaded 100 of 134 files, more files were not shown because too many files have changed in this diff. Show more