Commit 3c577146aa6 for nodejs
commit 3c577146aa641755179bd07fab9db1a18993091f
Author: Marco Ippolito <marcoippolito54@gmail.com>
Date: Thu Oct 1 11:47:11 2026 +0200
src: mark config file as stable
Signed-off-by: Marco Ippolito <marcoippolito54@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/66431
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Edy Silva <edigleyssonsilva@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Pietro Marchini <pietro.marchini94@gmail.com>
diff --git a/doc/api/cli.md b/doc/api/cli.md
index 4e17d81169d..fb764c01edd 100644
--- a/doc/api/cli.md
+++ b/doc/api/cli.md
@@ -799,6 +799,163 @@ For example, to run a module with "development" resolutions:
node -C development app.js
```
+### `--config-file=path`, `--config-file`
+
+<!-- YAML
+added:
+ - v23.10.0
+ - v22.16.0
+changes:
+ - version: REPLACEME
+ pr-url: https://github.com/nodejs/node/pull/66431
+ description: This flag was renamed from `--experimental-config-file` to
+ `--config-file` and is now stable. `--experimental-config-file`
+ and `--experimental-default-config-file` are kept as aliases.
+ - version: v26.7.0
+ pr-url: https://github.com/nodejs/node/pull/64516
+ description: Marked as release candidate.
+-->
+
+If present, Node.js will look for a configuration file at the specified path.
+If the path is not specified, Node.js will look for a `node.config.json` file
+in the current working directory.
+To specify a custom path, use the `--config-file=path` form.
+The space-separated `--config-file path` form is not supported.
+Node.js will read the configuration file and apply the settings. The
+configuration file should be a JSON file with the following structure. `vX.Y.Z`
+in the `$schema` must be replaced with the version of Node.js you are using or
+`latest-vX.x` for the latest version of that major release line.
+
+```json
+{
+ "$schema": "https://nodejs.org/dist/vX.Y.Z/docs/node-config-schema.json",
+ "nodeOptions": {
+ "import": [
+ "amaro/strip"
+ ],
+ "watch-path": "src",
+ "watch-preserve-output": true
+ },
+ "test": {
+ "test-isolation": "process"
+ },
+ "watch": {
+ "watch-preserve-output": true
+ }
+}
+```
+
+The configuration file supports namespace-specific options:
+
+* The `nodeOptions` field contains CLI flags that are allowed in [`NODE_OPTIONS`][].
+
+* Namespace fields like `test`, `watch`, and `permission` contain configuration specific to that subsystem.
+
+The configuration file can target a specific Node.js major version with
+`nodeVersion`:
+
+```json
+{
+ "nodeVersion": 25,
+ "nodeOptions": {
+ "watch-path": "src"
+ }
+}
+```
+
+To keep multiple version-specific configurations in the same file, use the
+`configs` array. Node.js will use the first entry whose `nodeVersion` matches
+the current Node.js major version:
+
+```json
+{
+ "$schema": "https://nodejs.org/dist/latest-v26.x/docs/node-config-schema.json",
+ "configs": [
+ {
+ "nodeVersion": 25,
+ "config": {
+ "$schema": "https://nodejs.org/dist/latest-v25.x/docs/node-config-schema.json",
+ "nodeOptions": {
+ "watch-path": "src"
+ }
+ }
+ }
+ ]
+}
+```
+
+When `configs` is used, the top level may only contain `$schema` and
+`configs`. Each `configs` item must define an integer `nodeVersion` and an
+object `config`. A single top-level config does not require `nodeVersion`, but
+if present it must match the current Node.js major version.
+
+When a namespace is present in the
+configuration file, Node.js automatically enables the corresponding flag
+(e.g., `--test`, `--watch`, `--permission`). This allows you to configure
+subsystem-specific options without explicitly passing the flag on the command line.
+
+For example:
+
+```json
+{
+ "test": {
+ "test-isolation": "process"
+ }
+}
+```
+
+is equivalent to:
+
+```bash
+node --test --test-isolation=process
+```
+
+To disable the automatic flag while still using namespace options, you can
+explicitly set the flag to `false` within the namespace:
+
+```json
+{
+ "test": {
+ "test": false,
+ "test-isolation": "process"
+ }
+}
+```
+
+No-op flags are not supported.
+Not all V8 flags are currently supported.
+
+It is possible to use the [official JSON schema](../node-config-schema.json)
+to validate the configuration file, which may vary depending on the Node.js version.
+Each key in the configuration file corresponds to a flag that can be passed
+as a command-line argument. The value of the key is the value that would be
+passed to the flag.
+
+For example, the configuration file above is equivalent to
+the following command-line arguments:
+
+```bash
+node --import amaro/strip --watch-path=src --watch-preserve-output --test-isolation=process
+```
+
+The priority in configuration is as follows:
+
+1. NODE\_OPTIONS and command-line options
+2. Dotenv NODE\_OPTIONS
+3. Configuration file
+
+Values in the configuration file will not override the values in the environment
+variables, command-line options, or the `NODE_OPTIONS` env file parsed by the
+`--env-file` flag.
+
+Keys cannot be duplicated within the same or different namespaces.
+
+The configuration parser will throw an error if the configuration file contains
+unknown keys or keys that cannot be used in a namespace.
+
+Node.js will not sanitize or perform validation on the user-provided configuration,
+so **NEVER** use untrusted configuration files.
+
### `--cpu-prof`
<!-- YAML
@@ -1280,177 +1437,6 @@ added: v26.9.0
Enable the experimental `node:bench` module and command-line benchmark runner.
-### `--experimental-config-file=path`, `--experimental-config-file`
-
-<!-- YAML
-added:
- - v23.10.0
- - v22.16.0
-changes:
- - version: v26.7.0
- pr-url: https://github.com/nodejs/node/pull/64516
- description: Marked as release candidate.
--->
-
-> Stability: 1.2 - Release candidate
-
-If present, Node.js will look for a configuration file at the specified path.
-If the path is not specified, Node.js will look for a `node.config.json` file
-in the current working directory.
-To specify a custom path, use the `--experimental-config-file=path` form.
-The space-separated `--experimental-config-file path` form is not supported.
-The alias `--experimental-default-config-file` is equivalent to
-`--experimental-config-file` without an argument.
-Node.js will read the configuration file and apply the settings. The
-configuration file should be a JSON file with the following structure. `vX.Y.Z`
-in the `$schema` must be replaced with the version of Node.js you are using or
-`latest-vX.x` for the latest version of that major release line.
-
-```json
-{
- "$schema": "https://nodejs.org/dist/vX.Y.Z/docs/node-config-schema.json",
- "nodeOptions": {
- "import": [
- "amaro/strip"
- ],
- "watch-path": "src",
- "watch-preserve-output": true
- },
- "test": {
- "test-isolation": "process"
- },
- "watch": {
- "watch-preserve-output": true
- }
-}
-```
-
-The configuration file supports namespace-specific options:
-
-* The `nodeOptions` field contains CLI flags that are allowed in [`NODE_OPTIONS`][].
-
-* Namespace fields like `test`, `watch`, and `permission` contain configuration specific to that subsystem.
-
-The configuration file can target a specific Node.js major version with
-`nodeVersion`:
-
-```json
-{
- "nodeVersion": 25,
- "nodeOptions": {
- "watch-path": "src"
- }
-}
-```
-
-To keep multiple version-specific configurations in the same file, use the
-`configs` array. Node.js will use the first entry whose `nodeVersion` matches
-the current Node.js major version:
-
-```json
-{
- "$schema": "https://nodejs.org/dist/latest-v26.x/docs/node-config-schema.json",
- "configs": [
- {
- "nodeVersion": 25,
- "config": {
- "$schema": "https://nodejs.org/dist/latest-v25.x/docs/node-config-schema.json",
- "nodeOptions": {
- "watch-path": "src"
- }
- }
- }
- ]
-}
-```
-
-When `configs` is used, the top level may only contain `$schema` and
-`configs`. Each `configs` item must define an integer `nodeVersion` and an
-object `config`. A single top-level config does not require `nodeVersion`, but
-if present it must match the current Node.js major version.
-
-When a namespace is present in the
-configuration file, Node.js automatically enables the corresponding flag
-(e.g., `--test`, `--watch`, `--permission`). This allows you to configure
-subsystem-specific options without explicitly passing the flag on the command line.
-
-For example:
-
-```json
-{
- "test": {
- "test-isolation": "process"
- }
-}
-```
-
-is equivalent to:
-
-```bash
-node --test --test-isolation=process
-```
-
-To disable the automatic flag while still using namespace options, you can
-explicitly set the flag to `false` within the namespace:
-
-```json
-{
- "test": {
- "test": false,
- "test-isolation": "process"
- }
-}
-```
-
-No-op flags are not supported.
-Not all V8 flags are currently supported.
-
-It is possible to use the [official JSON schema](../node-config-schema.json)
-to validate the configuration file, which may vary depending on the Node.js version.
-Each key in the configuration file corresponds to a flag that can be passed
-as a command-line argument. The value of the key is the value that would be
-passed to the flag.
-
-For example, the configuration file above is equivalent to
-the following command-line arguments:
-
-```bash
-node --import amaro/strip --watch-path=src --watch-preserve-output --test-isolation=process
-```
-
-The priority in configuration is as follows:
-
-1. NODE\_OPTIONS and command-line options
-2. Dotenv NODE\_OPTIONS
-3. Configuration file
-
-Values in the configuration file will not override the values in the environment
-variables, command-line options, or the `NODE_OPTIONS` env file parsed by the
-`--env-file` flag.
-
-Keys cannot be duplicated within the same or different namespaces.
-
-The configuration parser will throw an error if the configuration file contains
-unknown keys or keys that cannot be used in a namespace.
-
-Node.js will not sanitize or perform validation on the user-provided configuration,
-so **NEVER** use untrusted configuration files.
-
-### `--experimental-default-config-file`
-
-<!-- YAML
-added:
- - v23.10.0
- - v22.16.0
--->
-
-> Stability: 1.0 - Early development
-
-This flag is an alias for `--experimental-config-file` without an argument.
-If present, Node.js will look for a
-`node.config.json` file in the current working directory and load it as a
-configuration file.
-
### `--experimental-dtls`
<!-- YAML
diff --git a/doc/api/permissions.md b/doc/api/permissions.md
index b531541f65f..27acf9d4c69 100644
--- a/doc/api/permissions.md
+++ b/doc/api/permissions.md
@@ -375,9 +375,9 @@ programs.
#### Configuration file support
In addition to passing permission flags on the command line, they can also be
-declared in a Node.js configuration file when using the experimental
-\[`--experimental-config-file`]\[] flag. Permission options must be placed inside
-the `permission` top-level object.
+declared in a Node.js configuration file when using the [`--config-file`][]
+flag. Permission options must be placed inside the `permission` top-level
+object.
Example `node.config.json`:
@@ -400,7 +400,7 @@ When the `permission` namespace is present in the configuration file, Node.js
automatically enables the `--permission` flag. Run with:
```console
-$ node --experimental-default-config-file app.js
+$ node --config-file app.js
```
A configuration file, like the `NODE_OPTIONS` defined in an [`--env-file`][]
@@ -410,7 +410,7 @@ enable the Permission Model, the `allow-env` values these files define can only
narrow the access that [`--allow-env`][] grants, and never widen it:
```console
-$ node --permission --allow-env=APP_* --experimental-config-file=node.config.json app.js
+$ node --permission --allow-env=APP_* --config-file=node.config.json app.js
```
With `"allow-env": ["*"]` in `node.config.json`, only the variables starting with
@@ -539,6 +539,7 @@ Developers relying on --permission to sandbox untrusted code should be aware tha
[`--allow-openssl-store`]: cli.md#--allow-openssl-store
[`--allow-wasi`]: cli.md#--allow-wasi
[`--allow-worker`]: cli.md#--allow-worker
+[`--config-file`]: cli.md#--config-filepath---config-file
[`--env-file-if-exists`]: cli.md#--env-file-if-existsfile
[`--env-file`]: cli.md#--env-filefile
[`--permission-audit`]: cli.md#--permission-audit
diff --git a/doc/api/test.md b/doc/api/test.md
index 8cdfa884589..77bf17544df 100644
--- a/doc/api/test.md
+++ b/doc/api/test.md
@@ -885,10 +885,9 @@ test runner functionality:
* `--experimental-test-tag-filter` - Filter expressions are validated by the parent
process and re-emitted to child processes
* `--watch` - Watch mode is handled at the parent level
-* `--experimental-default-config-file` - Config file loading is handled by the parent
* `--test-reporter` - Reporting is managed by the parent process
* `--test-reporter-destination` - Output destinations are controlled by the parent
-* `--experimental-config-file` - Config file paths are managed by the parent
+* `--config-file` - Config file paths are managed by the parent
* `--test-randomize` - Randomization is managed by the parent process and
propagated to child processes
* `--test-random-seed` - Randomization seed is managed by the parent process and
@@ -5051,7 +5050,7 @@ test.describe('my suite', (suite) => {
[`suite()`]: #suitename-options-fn
[`test()`]: #testname-options-fn
[code coverage]: #collecting-code-coverage
-[configuration files]: cli.md#--experimental-config-filepath---experimental-config-file
+[configuration files]: cli.md#--config-filepath---config-file
[describe options]: #describename-options-fn
[it options]: #testname-options-fn
[module customization hooks]: module.md#customization-hooks
diff --git a/doc/node.1 b/doc/node.1
index 70488dff26c..a9ef1243fbb 100644
--- a/doc/node.1
+++ b/doc/node.1
@@ -480,6 +480,130 @@ For example, to run a module with "development" resolutions:
node -C development app.js
.Ed
.
+.It Fl -config-file Ns = Ns Ar path , Fl -config-file
+If present, Node.js will look for a configuration file at the specified path.
+If the path is not specified, Node.js will look for a \fBnode.config.json\fR file
+in the current working directory.
+To specify a custom path, use the \fB--config-file=path\fR form.
+The space-separated \fB--config-file path\fR form is not supported.
+Node.js will read the configuration file and apply the settings. The
+configuration file should be a JSON file with the following structure. \fBvX.Y.Z\fR
+in the \fB$schema\fR must be replaced with the version of Node.js you are using or
+\fBlatest-vX.x\fR for the latest version of that major release line.
+.Bd -literal
+{
+ "$schema": "https://nodejs.org/dist/vX.Y.Z/docs/node-config-schema.json",
+ "nodeOptions": {
+ "import": [
+ "amaro/strip"
+ ],
+ "watch-path": "src",
+ "watch-preserve-output": true
+ },
+ "test": {
+ "test-isolation": "process"
+ },
+ "watch": {
+ "watch-preserve-output": true
+ }
+}
+.Ed
+The configuration file supports namespace-specific options:
+.Bl -bullet
+.It
+The \fBnodeOptions\fR field contains CLI flags that are allowed in \fBNODE_OPTIONS\fR.
+.It
+Namespace fields like \fBtest\fR, \fBwatch\fR, and \fBpermission\fR contain configuration specific to that subsystem.
+.El
+The configuration file can target a specific Node.js major version with
+\fBnodeVersion\fR:
+.Bd -literal
+{
+ "nodeVersion": 25,
+ "nodeOptions": {
+ "watch-path": "src"
+ }
+}
+.Ed
+To keep multiple version-specific configurations in the same file, use the
+\fBconfigs\fR array. Node.js will use the first entry whose \fBnodeVersion\fR matches
+the current Node.js major version:
+.Bd -literal
+{
+ "$schema": "https://nodejs.org/dist/latest-v26.x/docs/node-config-schema.json",
+ "configs": [
+ {
+ "nodeVersion": 25,
+ "config": {
+ "$schema": "https://nodejs.org/dist/latest-v25.x/docs/node-config-schema.json",
+ "nodeOptions": {
+ "watch-path": "src"
+ }
+ }
+ }
+ ]
+}
+.Ed
+When \fBconfigs\fR is used, the top level may only contain \fB$schema\fR and
+\fBconfigs\fR. Each \fBconfigs\fR item must define an integer \fBnodeVersion\fR and an
+object \fBconfig\fR. A single top-level config does not require \fBnodeVersion\fR, but
+if present it must match the current Node.js major version.
+When a namespace is present in the
+configuration file, Node.js automatically enables the corresponding flag
+(e.g., \fB--test\fR, \fB--watch\fR, \fB--permission\fR). This allows you to configure
+subsystem-specific options without explicitly passing the flag on the command line.
+For example:
+.Bd -literal
+{
+ "test": {
+ "test-isolation": "process"
+ }
+}
+.Ed
+is equivalent to:
+.Bd -literal
+node --test --test-isolation=process
+.Ed
+To disable the automatic flag while still using namespace options, you can
+explicitly set the flag to \fBfalse\fR within the namespace:
+.Bd -literal
+{
+ "test": {
+ "test": false,
+ "test-isolation": "process"
+ }
+}
+.Ed
+No-op flags are not supported.
+Not all V8 flags are currently supported.
+It is possible to use the official JSON schema
+to validate the configuration file, which may vary depending on the Node.js version.
+Each key in the configuration file corresponds to a flag that can be passed
+as a command-line argument. The value of the key is the value that would be
+passed to the flag.
+For example, the configuration file above is equivalent to
+the following command-line arguments:
+.Bd -literal
+node --import amaro/strip --watch-path=src --watch-preserve-output --test-isolation=process
+.Ed
+The priority in configuration is as follows:
+.Bl -bullet
+.It
+NODE_OPTIONS and command-line options
+.It
+Dotenv NODE_OPTIONS
+.It
+Configuration file
+.El
+Values in the configuration file will not override the values in the environment
+variables, command-line options, or the \fBNODE_OPTIONS\fR env file parsed by the
+\fB--env-file\fR flag.
+Keys cannot be duplicated within the same or different namespaces.
+The configuration parser will throw an error if the configuration file contains
+unknown keys or keys that cannot be used in a namespace.
+Node.js will not sanitize or perform validation on the user-provided configuration,
+so \fBNEVER\fR use untrusted configuration files.
+.
.It Fl -cpu-prof
Starts the V8 CPU profiler on start up, and writes the CPU profile to disk
before exit.
@@ -722,138 +846,6 @@ Enable experimental import support for \fB.node\fR addons.
.It Fl -experimental-bench
Enable the experimental \fBnode:bench\fR module and command-line benchmark runner.
.
-.It Fl -experimental-config-file Ns = Ns Ar path , Fl -experimental-config-file
-If present, Node.js will look for a configuration file at the specified path.
-If the path is not specified, Node.js will look for a \fBnode.config.json\fR file
-in the current working directory.
-To specify a custom path, use the \fB--experimental-config-file=path\fR form.
-The space-separated \fB--experimental-config-file path\fR form is not supported.
-The alias \fB--experimental-default-config-file\fR is equivalent to
-\fB--experimental-config-file\fR without an argument.
-Node.js will read the configuration file and apply the settings. The
-configuration file should be a JSON file with the following structure. \fBvX.Y.Z\fR
-in the \fB$schema\fR must be replaced with the version of Node.js you are using or
-\fBlatest-vX.x\fR for the latest version of that major release line.
-.Bd -literal
-{
- "$schema": "https://nodejs.org/dist/vX.Y.Z/docs/node-config-schema.json",
- "nodeOptions": {
- "import": [
- "amaro/strip"
- ],
- "watch-path": "src",
- "watch-preserve-output": true
- },
- "test": {
- "test-isolation": "process"
- },
- "watch": {
- "watch-preserve-output": true
- }
-}
-.Ed
-The configuration file supports namespace-specific options:
-.Bl -bullet
-.It
-The \fBnodeOptions\fR field contains CLI flags that are allowed in \fBNODE_OPTIONS\fR.
-.It
-Namespace fields like \fBtest\fR, \fBwatch\fR, and \fBpermission\fR contain configuration specific to that subsystem.
-.El
-The configuration file can target a specific Node.js major version with
-\fBnodeVersion\fR:
-.Bd -literal
-{
- "nodeVersion": 25,
- "nodeOptions": {
- "watch-path": "src"
- }
-}
-.Ed
-To keep multiple version-specific configurations in the same file, use the
-\fBconfigs\fR array. Node.js will use the first entry whose \fBnodeVersion\fR matches
-the current Node.js major version:
-.Bd -literal
-{
- "$schema": "https://nodejs.org/dist/latest-v26.x/docs/node-config-schema.json",
- "configs": [
- {
- "nodeVersion": 25,
- "config": {
- "$schema": "https://nodejs.org/dist/latest-v25.x/docs/node-config-schema.json",
- "nodeOptions": {
- "watch-path": "src"
- }
- }
- }
- ]
-}
-.Ed
-When \fBconfigs\fR is used, the top level may only contain \fB$schema\fR and
-\fBconfigs\fR. Each \fBconfigs\fR item must define an integer \fBnodeVersion\fR and an
-object \fBconfig\fR. A single top-level config does not require \fBnodeVersion\fR, but
-if present it must match the current Node.js major version.
-When a namespace is present in the
-configuration file, Node.js automatically enables the corresponding flag
-(e.g., \fB--test\fR, \fB--watch\fR, \fB--permission\fR). This allows you to configure
-subsystem-specific options without explicitly passing the flag on the command line.
-For example:
-.Bd -literal
-{
- "test": {
- "test-isolation": "process"
- }
-}
-.Ed
-is equivalent to:
-.Bd -literal
-node --test --test-isolation=process
-.Ed
-To disable the automatic flag while still using namespace options, you can
-explicitly set the flag to \fBfalse\fR within the namespace:
-.Bd -literal
-{
- "test": {
- "test": false,
- "test-isolation": "process"
- }
-}
-.Ed
-No-op flags are not supported.
-Not all V8 flags are currently supported.
-It is possible to use the official JSON schema
-to validate the configuration file, which may vary depending on the Node.js version.
-Each key in the configuration file corresponds to a flag that can be passed
-as a command-line argument. The value of the key is the value that would be
-passed to the flag.
-For example, the configuration file above is equivalent to
-the following command-line arguments:
-.Bd -literal
-node --import amaro/strip --watch-path=src --watch-preserve-output --test-isolation=process
-.Ed
-The priority in configuration is as follows:
-.Bl -bullet
-.It
-NODE_OPTIONS and command-line options
-.It
-Dotenv NODE_OPTIONS
-.It
-Configuration file
-.El
-Values in the configuration file will not override the values in the environment
-variables, command-line options, or the \fBNODE_OPTIONS\fR env file parsed by the
-\fB--env-file\fR flag.
-Keys cannot be duplicated within the same or different namespaces.
-The configuration parser will throw an error if the configuration file contains
-unknown keys or keys that cannot be used in a namespace.
-Node.js will not sanitize or perform validation on the user-provided configuration,
-so \fBNEVER\fR use untrusted configuration files.
-.
-.It Fl -experimental-default-config-file
-This flag is an alias for \fB--experimental-config-file\fR without an argument.
-If present, Node.js will look for a
-\fBnode.config.json\fR file in the current working directory and load it as a
-configuration file.
-.
.It Fl -experimental-dtls
Enable experimental support for the DTLS protocol. See the
dtls documentation for details.
diff --git a/lib/internal/bench_runner/cli.js b/lib/internal/bench_runner/cli.js
index 96930ca5687..48af55c9cf1 100644
--- a/lib/internal/bench_runner/cli.js
+++ b/lib/internal/bench_runner/cli.js
@@ -118,6 +118,7 @@ const kFilterArgValues = [
'--bench-reporter-destination',
'--bench-samples',
'--bench-warmup',
+ '--config-file',
'--experimental-config-file',
];
const kIncompatibleExecArgv = new SafeSet([
@@ -652,7 +653,8 @@ function filterExecArgv(arg, index, args) {
return !ArrayPrototypeIncludes(kFilterArgs, name) &&
!ArrayPrototypeSome(kFilterArgValues, (option) => {
return name === option ||
- (option !== '--experimental-config-file' &&
+ (option !== '--config-file' &&
+ option !== '--experimental-config-file' &&
index > 0 &&
StringPrototypeIndexOf(args[index - 1], '=') === -1 &&
getOptionName(args[index - 1]) === option);
diff --git a/lib/internal/debugger/inspect_helpers.js b/lib/internal/debugger/inspect_helpers.js
index 68d7901b38c..f77a4c8d189 100644
--- a/lib/internal/debugger/inspect_helpers.js
+++ b/lib/internal/debugger/inspect_helpers.js
@@ -113,7 +113,8 @@ function validateChildArgs(childArgs) {
const arg = shiftArg();
if (arg === '--') { break; }
if (!isSynthetic &&
- (arg === '--experimental-config-file' ||
+ (arg === '--config-file' ||
+ arg === '--experimental-config-file' ||
arg === '--experimental-default-config-file')) {
// ConfigReader rewrites these to an inline default path before parsing.
continue;
diff --git a/lib/internal/main/watch_mode.js b/lib/internal/main/watch_mode.js
index 21889b0304f..8d6b2b23dd1 100644
--- a/lib/internal/main/watch_mode.js
+++ b/lib/internal/main/watch_mode.js
@@ -68,7 +68,9 @@ for (let i = 0; i < process.execArgv.length; i++) {
}
continue;
}
- if (arg === '--experimental-config-file' ||
+ if (arg === '--config-file' ||
+ StringPrototypeStartsWith(arg, '--config-file=') ||
+ arg === '--experimental-config-file' ||
StringPrototypeStartsWith(arg, '--experimental-config-file=')) {
continue;
}
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
index 9efccb40f8c..0f5aaf857ae 100644
--- a/lib/internal/process/pre_execution.js
+++ b/lib/internal/process/pre_execution.js
@@ -135,8 +135,6 @@ function prepareExecution(options) {
initializeSourceMapsHandlers();
initializeDeprecations();
- initializeConfigFileSupport();
-
// internal/dns/utils (and internal/net behind it) is only needed up front
// to validate an explicit --dns-result-order or to register the resolver's
// snapshot serialization; otherwise it is loaded with node:dns.
@@ -490,12 +488,6 @@ function setupOptionGatedBuiltins() {
BuiltinModule.allowOptionGatedBuiltins(getOptionValue);
}
-function initializeConfigFileSupport() {
- if (getOptionValue('--experimental-config-file')) {
- emitExperimentalWarning('--experimental-config-file');
- }
-}
-
function setupWebStorage() {
if (getEmbedderOptions().noBrowserGlobals ||
!getOptionValue('--experimental-webstorage')) {
diff --git a/lib/internal/test_runner/runner.js b/lib/internal/test_runner/runner.js
index 98947c742b2..03ab8ee1c63 100644
--- a/lib/internal/test_runner/runner.js
+++ b/lib/internal/test_runner/runner.js
@@ -118,6 +118,7 @@ const kFilterArgValues = [
'--test-reporter',
'--test-reporter-destination',
'--test-random-seed',
+ '--config-file',
'--experimental-config-file',
];
const kDiagnosticsFilterArgs = ['tests', 'suites', 'pass', 'fail', 'cancelled', 'skipped', 'todo', 'duration_ms'];
@@ -194,7 +195,8 @@ function filterExecArgv(arg, i, arr) {
!ArrayPrototypeSome(kFilterArgValues, (p) => {
return arg === p ||
StringPrototypeStartsWith(arg, `${p}=`) ||
- (p !== '--experimental-config-file' && i > 0 && arr[i - 1] === p);
+ (p !== '--config-file' && p !== '--experimental-config-file' &&
+ i > 0 && arr[i - 1] === p);
});
}
diff --git a/src/node_config_file.cc b/src/node_config_file.cc
index 73d2342d81f..0a44da48413 100644
--- a/src/node_config_file.cc
+++ b/src/node_config_file.cc
@@ -7,7 +7,10 @@
namespace node {
-constexpr std::string_view kConfigFileFlag = "--experimental-config-file";
+constexpr std::string_view kConfigFileFlag = "--config-file";
+// TODO(marco-ippolito): Remove these aliases in a semver-major.
+constexpr std::string_view kExperimentalConfigFileFlag =
+ "--experimental-config-file";
constexpr std::string_view kDefaultConfigFileFlag =
"--experimental-default-config-file";
constexpr std::string_view kDefaultConfigFileName = "node.config.json";
@@ -26,23 +29,20 @@ std::optional<std::string_view> ConfigReader::GetDataFromArgs(
for (size_t i = 0; i < args->size(); ++i) {
std::string& arg = (*args)[i];
- if (arg == kConfigFileFlag) {
- // --experimental-config-file
+ if (arg == kConfigFileFlag || arg == kExperimentalConfigFileFlag ||
+ arg == kDefaultConfigFileFlag) {
+ // --config-file, --experimental-config-file or
+ // --experimental-default-config-file
arg = std::string(kConfigFileFlag) + "=" +
std::string(kDefaultConfigFileName);
result = kDefaultConfigFileName;
- } else if (HasEqualsPrefix(arg, kConfigFileFlag)) {
- // --experimental-config-file=path
- std::string_view path =
- std::string_view(arg).substr(kConfigFileFlag.size() + 1);
+ } else if (HasEqualsPrefix(arg, kConfigFileFlag) ||
+ HasEqualsPrefix(arg, kExperimentalConfigFileFlag)) {
+ // --config-file=path or --experimental-config-file=path
+ std::string_view path = std::string_view(arg).substr(arg.find('=') + 1);
if (!path.empty()) {
result = path;
}
- } else if (arg == kDefaultConfigFileFlag) {
- // --experimental-default-config-file
- arg = std::string(kConfigFileFlag) + "=" +
- std::string(kDefaultConfigFileName);
- result = kDefaultConfigFileName;
} else if (HasEqualsPrefix(arg, kDefaultConfigFileFlag)) {
invalid_default_config_file_argument_ = true;
}
diff --git a/src/node_config_file.h b/src/node_config_file.h
index cc8d8e4c4c2..d6775aa8f69 100644
--- a/src/node_config_file.h
+++ b/src/node_config_file.h
@@ -23,7 +23,7 @@ namespace node {
enum ParseResult { Valid, FileError, InvalidContent };
// ConfigReader is the class that parses the configuration JSON file.
-// It reads the file provided by --experimental-config-file and
+// It reads the file provided by --config-file and
// extracts the flags.
class ConfigReader {
public:
diff --git a/src/node_options.cc b/src/node_options.cc
index c46b3baa775..acd98e6b927 100644
--- a/src/node_options.cc
+++ b/src/node_options.cc
@@ -1117,11 +1117,12 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
"set environment variables from supplied file",
&EnvironmentOptions::optional_env_file);
Implies("--env-file-if-exists", "[has_env_file_string]");
- AddOption("--experimental-config-file",
+ AddOption("--config-file",
"set config file path",
- &EnvironmentOptions::experimental_config_file_path,
+ &EnvironmentOptions::config_file_path,
kDisallowedInEnvvar);
- AddAlias("--experimental-default-config-file", "--experimental-config-file");
+ AddAlias("--experimental-config-file", "--config-file");
+ AddAlias("--experimental-default-config-file", "--config-file");
AddOption("--experimental-package-map",
"use the specified file for package map resolution",
&EnvironmentOptions::experimental_package_map_path,
diff --git a/src/node_options.h b/src/node_options.h
index ae3ddeb3120..37e05101f56 100644
--- a/src/node_options.h
+++ b/src/node_options.h
@@ -150,7 +150,7 @@ class EnvironmentOptions : public Options {
std::string watch_mode_kill_signal = "SIGTERM";
std::string eval_string;
std::string tls_keylog;
- std::string experimental_config_file_path;
+ std::string config_file_path;
std::string experimental_package_map_path;
std::string vfs_load_source;
#if HAVE_INSPECTOR
diff --git a/test/fixtures/test-runner/options-propagation/experimental-config-file.test.mjs b/test/fixtures/test-runner/options-propagation/config-file.test.mjs
similarity index 50%
rename from test/fixtures/test-runner/options-propagation/experimental-config-file.test.mjs
rename to test/fixtures/test-runner/options-propagation/config-file.test.mjs
index aa36ec2b52d..ade5a31be01 100644
--- a/test/fixtures/test-runner/options-propagation/experimental-config-file.test.mjs
+++ b/test/fixtures/test-runner/options-propagation/config-file.test.mjs
@@ -2,7 +2,7 @@ import { test } from 'node:test';
import { strictEqual } from 'node:assert';
import internal from 'internal/options';
-test('it should not receive --experimental-config-file option', () => {
- const optionValue = internal.getOptionValue("--experimental-config-file");
+test('it should not receive --config-file option', () => {
+ const optionValue = internal.getOptionValue("--config-file");
strictEqual(optionValue, '');
})
diff --git a/test/parallel/test-bench-cli.js b/test/parallel/test-bench-cli.js
index df1c6edeb22..e36532ce2d0 100644
--- a/test/parallel/test-bench-cli.js
+++ b/test/parallel/test-bench-cli.js
@@ -428,7 +428,7 @@ if (common.hasInspector) {
const result = spawnNode([
'--no-warnings',
'--experimental-bench',
- `--experimental-config-file=${fixtures.path('bench-runner/node.config.json')}`,
+ `--config-file=${fixtures.path('bench-runner/node.config.json')}`,
fixtures.path('bench-runner/a.cjs'),
]);
assert.strictEqual(result.status, 0);
diff --git a/test/parallel/test-cli-node-options-docs.js b/test/parallel/test-cli-node-options-docs.js
index 534c99c04de..80caa29d426 100644
--- a/test/parallel/test-cli-node-options-docs.js
+++ b/test/parallel/test-cli-node-options-docs.js
@@ -122,6 +122,5 @@ for (const [, envVar, config] of nodeOptionsCC.matchAll(addOptionRE)) {
// add alias handling
manPagesOptions.delete('-trace-events-enabled');
-manPagesOptions.delete('-experimental-default-config-file');
assert.strictEqual(manPagesOptions.size, 0, `Man page options not documented: ${[...manPagesOptions]}`);
diff --git a/test/parallel/test-cli-options-as-flags.js b/test/parallel/test-cli-options-as-flags.js
index ed87ba3e1fa..43f8df8a2ac 100644
--- a/test/parallel/test-cli-options-as-flags.js
+++ b/test/parallel/test-cli-options-as-flags.js
@@ -56,7 +56,7 @@ describe('getOptionsAsFlagsFromBinding', () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
'--expose-internals',
- `--experimental-config-file=${configFile}`,
+ `--config-file=${configFile}`,
fixtureFile,
]);
@@ -75,7 +75,7 @@ describe('getOptionsAsFlagsFromBinding', () => {
'--no-warnings',
'--expose-internals',
'--stack-trace-limit=512',
- `--experimental-config-file=${configFile}`,
+ `--config-file=${configFile}`,
fixtureFile,
]);
diff --git a/test/parallel/test-config-file.js b/test/parallel/test-config-file.js
index 104853cdcbe..d81b1703549 100644
--- a/test/parallel/test-config-file.js
+++ b/test/parallel/test-config-file.js
@@ -24,7 +24,7 @@ const onlyWithInspectorAndNodeOptions = {
test('should handle non existing json', async () => {
const result = await spawnPromisified(process.execPath, [
- '--experimental-config-file=i-do-not-exist.json',
+ '--config-file=i-do-not-exist.json',
'-p', '"Hello, World!"',
]);
assert.match(result.stderr, /Cannot read configuration from i-do-not-exist\.json: no such file or directory/);
@@ -35,7 +35,7 @@ test('should handle non existing json', async () => {
test('should handle empty json', async () => {
const result = await spawnPromisified(process.execPath, [
- `--experimental-config-file=${fixtures.path('rc/empty.json')}`,
+ `--config-file=${fixtures.path('rc/empty.json')}`,
'-p', '"Hello, World!"',
]);
assert.match(result.stderr, /Can't parse/);
@@ -47,7 +47,7 @@ test('should handle empty json', async () => {
test('should handle empty object json', async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/empty-object.json')}`,
+ `--config-file=${fixtures.path('rc/empty-object.json')}`,
'-p', '"Hello, World!"',
]);
assert.strictEqual(result.stderr, '');
@@ -65,7 +65,7 @@ describe('runtime version checks', () => {
return spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${configPath}`,
+ `--config-file=${configPath}`,
'-p', 'http.maxHeaderSize',
]);
}
@@ -284,17 +284,17 @@ describe('runtime version checks', () => {
test('should parse boolean flag', onlyWithAmaroAndNodeOptions, async () => {
const result = await spawnPromisified(process.execPath, [
- `--experimental-config-file=${fixtures.path('rc/strip-types.json')}`,
+ `--config-file=${fixtures.path('rc/strip-types.json')}`,
fixtures.path('typescript/ts/test-typescript.ts'),
]);
- assert.match(result.stderr, /--experimental-config-file is an experimental feature and might change at any time/);
+ assert.strictEqual(result.stderr, '');
assert.match(result.stdout, /Hello, TypeScript!/);
assert.strictEqual(result.code, 0);
});
test('should parse boolean flag defaulted to true', onlyIfNodeOptionsSupport, async () => {
const result = await spawnPromisified(process.execPath, [
- `--experimental-config-file=${fixtures.path('rc/warnings-false.json')}`,
+ `--config-file=${fixtures.path('rc/warnings-false.json')}`,
'-p', 'process.emitWarning("A warning")',
]);
assert.strictEqual(result.stderr, '');
@@ -305,7 +305,7 @@ test('should parse boolean flag defaulted to true', onlyIfNodeOptionsSupport, as
test('should throw an error when a flag is declared twice', async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/override-property.json')}`,
+ `--config-file=${fixtures.path('rc/override-property.json')}`,
'-p', '"Hello, World!"',
]);
assert.match(result.stderr, /Option --strip-types is already defined/);
@@ -316,7 +316,7 @@ test('should throw an error when a flag is declared twice', async () => {
test('should not override env-file', onlyWithAmaroAndNodeOptions, async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/strip-types.json')}`,
+ `--config-file=${fixtures.path('rc/strip-types.json')}`,
'--env-file', fixtures.path('dotenv/node-options-no-tranform.env'),
fixtures.path('typescript/ts/test-typescript.ts'),
]);
@@ -328,7 +328,7 @@ test('should not override env-file', onlyWithAmaroAndNodeOptions, async () => {
test('should not override NODE_OPTIONS', onlyWithAmaro, async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/strip-types.json')}`,
+ `--config-file=${fixtures.path('rc/strip-types.json')}`,
fixtures.path('typescript/ts/test-typescript.ts'),
], {
env: {
@@ -345,7 +345,7 @@ test('should not override CLI flags', onlyWithAmaro, async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
'--no-strip-types',
- `--experimental-config-file=${fixtures.path('rc/strip-types.json')}`,
+ `--config-file=${fixtures.path('rc/strip-types.json')}`,
fixtures.path('typescript/ts/test-typescript.ts'),
]);
assert.match(result.stderr, /SyntaxError/);
@@ -356,7 +356,7 @@ test('should not override CLI flags', onlyWithAmaro, async () => {
test('should parse array flag correctly', onlyIfNodeOptionsSupport, async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/import.json')}`,
+ `--config-file=${fixtures.path('rc/import.json')}`,
'--eval', 'setTimeout(() => console.log("D"),99)',
]);
assert.strictEqual(result.stderr, '');
@@ -367,7 +367,7 @@ test('should parse array flag correctly', onlyIfNodeOptionsSupport, async () =>
test('should validate invalid array flag', async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/invalid-import.json')}`,
+ `--config-file=${fixtures.path('rc/invalid-import.json')}`,
'--eval', 'setTimeout(() => console.log("D"),99)',
]);
assert.match(result.stderr, /invalid-import\.json: invalid content/);
@@ -378,7 +378,7 @@ test('should validate invalid array flag', async () => {
test('should validate array flag as string', onlyIfNodeOptionsSupport, async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/import-as-string.json')}`,
+ `--config-file=${fixtures.path('rc/import-as-string.json')}`,
'--eval', 'setTimeout(() => console.log("B"),99)',
]);
assert.strictEqual(result.stderr, '');
@@ -389,7 +389,7 @@ test('should validate array flag as string', onlyIfNodeOptionsSupport, async ()
test('should throw at unknown flag', async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/unknown-flag.json')}`,
+ `--config-file=${fixtures.path('rc/unknown-flag.json')}`,
'-p', '"Hello, World!"',
]);
assert.match(result.stderr, /Unknown or not allowed option some-unknown-flag for namespace nodeOptions/);
@@ -400,7 +400,7 @@ test('should throw at unknown flag', async () => {
test('should throw at flag not available in NODE_OPTIONS', async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/not-node-options-flag.json')}`,
+ `--config-file=${fixtures.path('rc/not-node-options-flag.json')}`,
'-p', '"Hello, World!"',
]);
assert.match(result.stderr, /Unknown or not allowed option test for namespace nodeOptions/);
@@ -411,7 +411,7 @@ test('should throw at flag not available in NODE_OPTIONS', async () => {
test('unsigned flag should be parsed correctly', onlyIfNodeOptionsSupport, async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/numeric.json')}`,
+ `--config-file=${fixtures.path('rc/numeric.json')}`,
'-p', 'http.maxHeaderSize',
]);
assert.strictEqual(result.stderr, '');
@@ -422,7 +422,7 @@ test('unsigned flag should be parsed correctly', onlyIfNodeOptionsSupport, async
test('numeric flag should not allow negative values', async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/negative-numeric.json')}`,
+ `--config-file=${fixtures.path('rc/negative-numeric.json')}`,
'-p', 'http.maxHeaderSize',
]);
assert.match(result.stderr, /Invalid value for --max-http-header-size/);
@@ -434,7 +434,7 @@ test('numeric flag should not allow negative values', async () => {
test('v8 flag should not be allowed in config file', async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/v8-flag.json')}`,
+ `--config-file=${fixtures.path('rc/v8-flag.json')}`,
'-p', '"Hello, World!"',
]);
assert.match(result.stderr, /V8 flag --abort-on-uncaught-exception is currently not supported/);
@@ -446,7 +446,7 @@ test('string flag should be parsed correctly', onlyIfNodeOptionsSupport, async (
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
'--test',
- `--experimental-config-file=${fixtures.path('rc/string.json')}`,
+ `--config-file=${fixtures.path('rc/string.json')}`,
fixtures.path('rc/test.js'),
]);
assert.strictEqual(result.stderr, '');
@@ -458,7 +458,7 @@ test('host port flag should be parsed correctly', onlyWithInspectorAndNodeOption
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
'--expose-internals',
- `--experimental-config-file=${fixtures.path('rc/host-port.json')}`,
+ `--config-file=${fixtures.path('rc/host-port.json')}`,
'-p', 'require("internal/options").getOptionValue("--inspect-port").port',
]);
assert.strictEqual(result.stderr, '');
@@ -469,7 +469,7 @@ test('host port flag should be parsed correctly', onlyWithInspectorAndNodeOption
test('--inspect=true should be parsed correctly', onlyWithInspectorAndNodeOptions, async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/inspect-true.json')}`,
+ `--config-file=${fixtures.path('rc/inspect-true.json')}`,
'--inspect-port', '0',
'-p', 'require("node:inspector").url()',
]);
@@ -481,7 +481,7 @@ test('--inspect=true should be parsed correctly', onlyWithInspectorAndNodeOption
test('--inspect=false should be parsed correctly', { skip: !process.features.inspector }, async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/inspect-false.json')}`,
+ `--config-file=${fixtures.path('rc/inspect-false.json')}`,
'-p', 'require("node:inspector").url()',
]);
assert.strictEqual(result.stderr, '');
@@ -492,7 +492,7 @@ test('--inspect=false should be parsed correctly', { skip: !process.features.ins
test('no op flag should throw', async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/no-op.json')}`,
+ `--config-file=${fixtures.path('rc/no-op.json')}`,
'-p', '"Hello, World!"',
]);
assert.match(result.stderr, /No-op flag --http-parser is currently not supported/);
@@ -504,7 +504,7 @@ test('no op flag should throw', async () => {
test('should not allow users to sneak in a flag', async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/sneaky-flag.json')}`,
+ `--config-file=${fixtures.path('rc/sneaky-flag.json')}`,
'-p', '"Hello, World!"',
]);
assert.match(result.stderr, /The number of NODE_OPTIONS doesn't match the number of flags in the config file/);
@@ -515,7 +515,7 @@ test('should not allow users to sneak in a flag', async () => {
test('non object root', async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/non-object-root.json')}`,
+ `--config-file=${fixtures.path('rc/non-object-root.json')}`,
'-p', '"Hello, World!"',
]);
assert.match(result.stderr, /Root value unexpected not an object for/);
@@ -526,7 +526,7 @@ test('non object root', async () => {
test('non object node options', async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/non-object-node-options.json')}`,
+ `--config-file=${fixtures.path('rc/non-object-node-options.json')}`,
'-p', '"Hello, World!"',
]);
assert.match(result.stderr, /"nodeOptions" value unexpected for/);
@@ -537,7 +537,7 @@ test('non object node options', async () => {
test('should throw correct error when a json is broken', async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/broken.json')}`,
+ `--config-file=${fixtures.path('rc/broken.json')}`,
'-p', '"Hello, World!"',
]);
assert.match(result.stderr, /Can't parse/);
@@ -549,7 +549,7 @@ test('should throw correct error when a json is broken', async () => {
test('broken value in node_options', async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/broken-node-options.json')}`,
+ `--config-file=${fixtures.path('rc/broken-node-options.json')}`,
'-p', '"Hello, World!"',
]);
assert.match(result.stderr, /Can't parse/);
@@ -571,11 +571,11 @@ test('should use node.config.json as default', onlyIfNodeOptionsSupport, async (
assert.strictEqual(result.code, 0);
});
-test('should use node.config.json when --experimental-config-file has no argument',
+test('should use node.config.json when --config-file has no argument',
onlyIfNodeOptionsSupport, async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- '--experimental-config-file',
+ '--config-file',
'-p', 'http.maxHeaderSize',
], {
cwd: fixtures.path('rc/default'),
@@ -589,7 +589,7 @@ test('should not treat the script path as a config file argument',
onlyIfNodeOptionsSupport, async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- '--experimental-config-file',
+ '--config-file',
fixtures.path('printA.js'),
], {
cwd: fixtures.path('rc/default'),
@@ -603,7 +603,7 @@ test('should treat a space-separated config file path as the script',
onlyIfNodeOptionsSupport, async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- '--experimental-config-file',
+ '--config-file',
fixtures.path('rc/empty.json'),
fixtures.path('printA.js'),
], {
@@ -617,16 +617,16 @@ test('should treat a space-separated config file path as the script',
assert.strictEqual(result.code, 1);
});
-test('should error when --experimental-config-file= has empty argument',
+test('should error when --config-file= has empty argument',
onlyIfNodeOptionsSupport, async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- '--experimental-config-file=',
+ '--config-file=',
'-p', 'http.maxHeaderSize',
], {
cwd: fixtures.path('rc/default'),
});
- assert.match(result.stderr, /--experimental-config-file= requires an argument/);
+ assert.match(result.stderr, /--config-file= requires an argument/);
assert.strictEqual(result.code, 9);
});
@@ -647,7 +647,7 @@ test('should override node.config.json when specified', onlyIfNodeOptionsSupport
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
'--experimental-default-config-file',
- `--experimental-config-file=${fixtures.path('rc/default/override.json')}`,
+ `--config-file=${fixtures.path('rc/default/override.json')}`,
'-p', 'http.maxHeaderSize',
], {
cwd: fixtures.path('rc/default'),
@@ -657,11 +657,11 @@ test('should override node.config.json when specified', onlyIfNodeOptionsSupport
assert.strictEqual(result.code, 0);
});
-test('should work with --experimental-config-file=path',
+test('should work with --config-file=path',
onlyIfNodeOptionsSupport, async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/default/node.config.json')}`,
+ `--config-file=${fixtures.path('rc/default/node.config.json')}`,
'-p', 'http.maxHeaderSize',
]);
assert.strictEqual(result.stderr, '');
@@ -669,12 +669,33 @@ test('should work with --experimental-config-file=path',
assert.strictEqual(result.code, 0);
});
+test('should support the --experimental-config-file alias',
+ onlyIfNodeOptionsSupport, async () => {
+ const withPath = await spawnPromisified(process.execPath, [
+ `--experimental-config-file=${fixtures.path('rc/default/node.config.json')}`,
+ '-p', 'http.maxHeaderSize',
+ ]);
+ assert.strictEqual(withPath.stderr, '');
+ assert.strictEqual(withPath.stdout, '10\n');
+ assert.strictEqual(withPath.code, 0);
+
+ const withoutPath = await spawnPromisified(process.execPath, [
+ '--experimental-config-file',
+ '-p', 'http.maxHeaderSize',
+ ], {
+ cwd: fixtures.path('rc/default'),
+ });
+ assert.strictEqual(withoutPath.stderr, '');
+ assert.strictEqual(withoutPath.stdout, '10\n');
+ assert.strictEqual(withoutPath.code, 0);
+ });
+
test('should use last config file when multiple are specified',
onlyIfNodeOptionsSupport, async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/default/node.config.json')}`,
- `--experimental-config-file=${fixtures.path('rc/default/override.json')}`,
+ `--config-file=${fixtures.path('rc/default/node.config.json')}`,
+ `--config-file=${fixtures.path('rc/default/override.json')}`,
'-p', 'http.maxHeaderSize',
]);
assert.strictEqual(result.stderr, '');
@@ -686,7 +707,7 @@ test('should use default when next argument starts with dash',
onlyIfNodeOptionsSupport, async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- '--experimental-config-file',
+ '--config-file',
'-p', 'http.maxHeaderSize',
], {
cwd: fixtures.path('rc/default'),
@@ -724,7 +745,7 @@ describe('namespace-scoped options', () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
'--expose-internals',
- `--experimental-config-file=${fixtures.path('rc/namespaced/node.config.json')}`,
+ `--config-file=${fixtures.path('rc/namespaced/node.config.json')}`,
'--no-test',
'-p', 'require("internal/options").getOptionValue("--test-isolation")',
]);
@@ -736,7 +757,7 @@ describe('namespace-scoped options', () => {
it('should throw an error when a namespace-scoped option is not recognised', async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/unknown-flag-namespace.json')}`,
+ `--config-file=${fixtures.path('rc/unknown-flag-namespace.json')}`,
'-p', '"Hello, World!"',
]);
assert.match(result.stderr, /Unknown or not allowed option unknown-flag for namespace test/);
@@ -747,7 +768,7 @@ describe('namespace-scoped options', () => {
it('should throw an error when a namespace is not recognised', async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/unknown-namespace.json')}`,
+ `--config-file=${fixtures.path('rc/unknown-namespace.json')}`,
'-p', '"Hello, World!"',
]);
assert.match(result.stderr, /Unknown namespace an-invalid-namespace/);
@@ -759,7 +780,7 @@ describe('namespace-scoped options', () => {
it('should allow the $schema field', async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/schema.json')}`,
+ `--config-file=${fixtures.path('rc/schema.json')}`,
'-p', 'http.maxHeaderSize',
]);
assert.strictEqual(result.stderr, '');
@@ -770,7 +791,7 @@ describe('namespace-scoped options', () => {
it('should handle an empty namespace valid namespace', async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/empty-valid-namespace.json')}`,
+ `--config-file=${fixtures.path('rc/empty-valid-namespace.json')}`,
'-p', '"Hello, World!"',
]);
assert.strictEqual(result.stderr, '');
@@ -782,7 +803,7 @@ describe('namespace-scoped options', () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
'--expose-internals',
- `--experimental-config-file=${fixtures.path('rc/override-node-option-with-namespace.json')}`,
+ `--config-file=${fixtures.path('rc/override-node-option-with-namespace.json')}`,
'-p', 'require("internal/options").getOptionValue("--test-isolation")',
]);
assert.match(result.stderr, /Option --test-isolation is already defined/);
@@ -794,7 +815,7 @@ describe('namespace-scoped options', () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
'--expose-internals',
- `--experimental-config-file=${fixtures.path('rc/override-namespace.json')}`,
+ `--config-file=${fixtures.path('rc/override-namespace.json')}`,
'-p', 'require("internal/options").getOptionValue("--test-isolation")',
]);
assert.match(result.stderr, /Option --test-isolation is already defined/);
@@ -807,7 +828,7 @@ describe('namespace-scoped options', () => {
'--no-warnings',
'--expose-internals',
'--test-isolation', 'process',
- `--experimental-config-file=${fixtures.path('rc/namespaced/node.config.json')}`,
+ `--config-file=${fixtures.path('rc/namespaced/node.config.json')}`,
'--no-test',
'-p', 'require("internal/options").getOptionValue("--test-isolation")',
]);
@@ -822,7 +843,7 @@ describe('namespace-scoped options', () => {
'--expose-internals',
'--test-coverage-exclude', 'cli-pattern1',
'--test-coverage-exclude', 'cli-pattern2',
- `--experimental-config-file=${fixtures.path('rc/namespace-with-array.json')}`,
+ `--config-file=${fixtures.path('rc/namespace-with-array.json')}`,
'--no-test',
'-p', 'JSON.stringify(require("internal/options").getOptionValue("--test-coverage-exclude"))',
]);
@@ -844,7 +865,7 @@ describe('namespace-scoped options', () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
'--expose-internals',
- `--experimental-config-file=${fixtures.path('rc/namespace-with-disallowed-envvar.json')}`,
+ `--config-file=${fixtures.path('rc/namespace-with-disallowed-envvar.json')}`,
'--no-test',
'-p', 'require("internal/options").getOptionValue("--test-concurrency")',
]);
@@ -860,7 +881,7 @@ describe('namespace-scoped options', () => {
'--no-warnings',
'--expose-internals',
'--test-concurrency', '2',
- `--experimental-config-file=${fixtures.path('rc/namespace-with-disallowed-envvar.json')}`,
+ `--config-file=${fixtures.path('rc/namespace-with-disallowed-envvar.json')}`,
'--no-test',
'-p', 'require("internal/options").getOptionValue("--test-concurrency")',
]);
@@ -872,7 +893,7 @@ describe('namespace-scoped options', () => {
it('should throw an error for removed "testRunner" namespace', async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/deprecated-testrunner-namespace.json')}`,
+ `--config-file=${fixtures.path('rc/deprecated-testrunner-namespace.json')}`,
'-p', '"Hello, World!"',
]);
assert.match(result.stderr, /the "testRunner" namespace has been removed\. Use "test" instead\./);
@@ -883,7 +904,7 @@ describe('namespace-scoped options', () => {
it('should automatically enable --test flag when test namespace is present', async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
- `--experimental-config-file=${fixtures.path('rc/namespaced/node.config.json')}`,
+ `--config-file=${fixtures.path('rc/namespaced/node.config.json')}`,
fixtures.path('rc/test.js'),
]);
assert.strictEqual(result.code, 0);
@@ -894,7 +915,7 @@ describe('namespace-scoped options', () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
'--expose-internals',
- `--experimental-config-file=${fixtures.path('rc/permission-namespace.json')}`,
+ `--config-file=${fixtures.path('rc/permission-namespace.json')}`,
'-p', 'require("internal/options").getOptionValue("--permission")',
]);
assert.strictEqual(result.stderr, '');
@@ -906,7 +927,7 @@ describe('namespace-scoped options', () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
'--expose-internals',
- `--experimental-config-file=${fixtures.path('rc/test-namespace-explicit-false.json')}`,
+ `--config-file=${fixtures.path('rc/test-namespace-explicit-false.json')}`,
'-p', 'require("internal/options").getOptionValue("--test")',
]);
assert.strictEqual(result.stderr, '');
diff --git a/test/parallel/test-debugger-no-inspect-brk.js b/test/parallel/test-debugger-no-inspect-brk.js
index 611d28fd9f3..31a1edac0b8 100644
--- a/test/parallel/test-debugger-no-inspect-brk.js
+++ b/test/parallel/test-debugger-no-inspect-brk.js
@@ -120,6 +120,14 @@ assertSuccessfulProbe([
// ConfigReader rewrites these bare options to use the default path without
// consuming the following argument.
Promise.all([
+ assert.rejects(
+ launchChildProcess([
+ '--config-file',
+ '--no-inspect-brk',
+ 'probe.js',
+ ], '127.0.0.1', 0, () => {}),
+ incompatibleInspectBrk,
+ ),
assert.rejects(
launchChildProcess([
'--experimental-config-file',
diff --git a/test/parallel/test-permission-config-file.mjs b/test/parallel/test-permission-config-file.mjs
index bfa9d6b0189..6b01f3741f3 100644
--- a/test/parallel/test-permission-config-file.mjs
+++ b/test/parallel/test-permission-config-file.mjs
@@ -13,7 +13,7 @@ describe('Permission model config file support', () => {
{
const result = await spawnPromisified(process.execPath, [
'--permission',
- `--experimental-config-file=${readOnlyConfigPath}`,
+ `--config-file=${readOnlyConfigPath}`,
readTestPath,
]);
assert.strictEqual(result.code, 0);
@@ -22,7 +22,7 @@ describe('Permission model config file support', () => {
{
const result = await spawnPromisified(process.execPath, [
'--permission',
- `--experimental-config-file=${readWriteConfigPath}`,
+ `--config-file=${readWriteConfigPath}`,
writeTestPath,
]);
assert.strictEqual(result.code, 0);
@@ -31,7 +31,7 @@ describe('Permission model config file support', () => {
{
const result = await spawnPromisified(process.execPath, [
'--permission',
- `--experimental-config-file=${readOnlyConfigPath}`,
+ `--config-file=${readOnlyConfigPath}`,
writeTestPath,
]);
assert.strictEqual(result.code, 1);
@@ -47,7 +47,7 @@ describe('Permission model config file support', () => {
{
const result = await spawnPromisified(process.execPath, [
'--permission',
- `--experimental-config-file=${configPath}`,
+ `--config-file=${configPath}`,
childTestPath,
]);
assert.strictEqual(result.code, 0);
@@ -56,7 +56,7 @@ describe('Permission model config file support', () => {
{
const result = await spawnPromisified(process.execPath, [
'--permission',
- `--experimental-config-file=${readOnlyConfigPath}`,
+ `--config-file=${readOnlyConfigPath}`,
childTestPath,
]);
assert.strictEqual(result.code, 1, result.stderr);
@@ -71,7 +71,7 @@ describe('Permission model config file support', () => {
{
const result = await spawnPromisified(process.execPath, [
'--permission',
- `--experimental-config-file=${configPath}`,
+ `--config-file=${configPath}`,
'-p',
'process.permission.has("net") && process.permission.has("inspector")',
]);
@@ -82,7 +82,7 @@ describe('Permission model config file support', () => {
{
const result = await spawnPromisified(process.execPath, [
'--permission',
- `--experimental-config-file=${readOnlyConfigPath}`,
+ `--config-file=${readOnlyConfigPath}`,
'-p',
'process.permission.has("net") + process.permission.has("inspector")',
]);
@@ -96,7 +96,7 @@ describe('Permission model config file support', () => {
const result = await spawnPromisified(process.execPath, [
'--permission',
- `--experimental-config-file=${configPath}`,
+ `--config-file=${configPath}`,
'--allow-fs-read=*',
'-p',
'process.permission.has("addon") && process.permission.has("wasi")',
@@ -110,7 +110,7 @@ describe('Permission model config file support', () => {
const result = await spawnPromisified(process.execPath, [
'--permission',
- `--experimental-config-file=${configPath}`,
+ `--config-file=${configPath}`,
'--allow-child-process',
'--allow-fs-write=*',
'-p',
diff --git a/test/parallel/test-permission-env-config-file.js b/test/parallel/test-permission-env-config-file.js
index 21a1f4d6126..a46278b8449 100644
--- a/test/parallel/test-permission-env-config-file.js
+++ b/test/parallel/test-permission-env-config-file.js
@@ -58,19 +58,19 @@ assert.deepStrictEqual(
visible([
'--permission',
'--allow-env=PERMISSION_ENV_A',
- `--experimental-config-file=${bothConfig}`,
+ `--config-file=${bothConfig}`,
]),
['PERMISSION_ENV_A']);
assert.deepStrictEqual(
- visible(['--permission', `--experimental-config-file=${allConfig}`]),
+ visible(['--permission', `--config-file=${allConfig}`]),
[]);
assert.deepStrictEqual(
visible([
'--permission',
'--allow-env=PERMISSION_ENV_PREFIX_*',
- `--experimental-config-file=${prefixConfig}`,
+ `--config-file=${prefixConfig}`,
]),
['PERMISSION_ENV_PREFIX_DB_URL']);
@@ -86,7 +86,7 @@ assert.deepStrictEqual(
// When only the configuration file enables the permission model, its
// --allow-env values apply.
assert.deepStrictEqual(
- visible([`--experimental-config-file=${bothConfig}`]),
+ visible([`--config-file=${bothConfig}`]),
['PERMISSION_ENV_A', 'PERMISSION_ENV_B']);
// The NODE_OPTIONS environment variable is not a file, and can grant access.
diff --git a/test/parallel/test-runner-cli.js b/test/parallel/test-runner-cli.js
index 5a5e6b9bdf1..28ad56a0a93 100644
--- a/test/parallel/test-runner-cli.js
+++ b/test/parallel/test-runner-cli.js
@@ -454,6 +454,8 @@ for (const isolation of ['none', 'process']) {
// Should not propagate config file options to sub tests in isolation process.
const fixturePath = join(testFixtures, 'options-propagation');
const configFlagVariants = [
+ ['--config-file=node.config.json'],
+ ['--config-file'],
['--experimental-config-file=node.config.json'],
['--experimental-config-file'],
['--experimental-default-config-file'],
@@ -492,7 +494,7 @@ for (const isolation of ['none', 'process']) {
const args = [
'--test-reporter=tap',
'--no-warnings',
- `--experimental-config-file=node.config.json`,
+ `--config-file=node.config.json`,
'--expose-internals',
'--test',
];
diff --git a/test/parallel/test-runner-flag-propagation.js b/test/parallel/test-runner-flag-propagation.js
index 055d8b6d67c..afd7ae7a0ae 100644
--- a/test/parallel/test-runner-flag-propagation.js
+++ b/test/parallel/test-runner-flag-propagation.js
@@ -15,9 +15,11 @@ const runner = path.join(fixtureDir, 'runner.mjs');
describe('test runner flag propagation', () => {
describe('via command line', () => {
const flagPropagationTests = [
- ['--experimental-config-file=node.config.json', '', '', '--experimental-config-file',
+ ['--config-file=node.config.json', '', '', '--config-file',
+ 'should not propagate --config-file to child tests'],
+ ['--experimental-config-file=node.config.json', '', '', '--config-file',
'should not propagate --experimental-config-file to child tests'],
- ['--experimental-default-config-file', '', '', '--experimental-config-file',
+ ['--experimental-default-config-file', '', '', '--config-file',
'should not propagate --experimental-default-config-file to child tests'],
['--env-file', '.env', '.env'],
['--env-file-if-exists', '.env', '.env'],
@@ -108,7 +110,7 @@ describe('test runner flag propagation', () => {
'--test-reporter=tap',
'--no-warnings',
'--expose-internals',
- `--experimental-config-file=${configFile}`,
+ `--config-file=${configFile}`,
runner,
`--flag=${flagName}`,
`--expected=${expectedValue}`,
diff --git a/test/sequential/test-watch-mode.mjs b/test/sequential/test-watch-mode.mjs
index 8607331a94a..1fe4f0597cb 100644
--- a/test/sequential/test-watch-mode.mjs
+++ b/test/sequential/test-watch-mode.mjs
@@ -874,7 +874,7 @@ process.on('message', (message) => {
const file = createTmpFile();
const configFile = createTmpFile(JSON.stringify({ watch: { 'watch': true } }), '.json');
const { stderr, stdout } = await runWriteSucceed({
- file, watchedFile: file, args: [`--experimental-config-file=${configFile}`, file], options: {
+ file, watchedFile: file, args: [`--config-file=${configFile}`, file], options: {
timeout: 10000,
},
});
@@ -899,7 +899,7 @@ process.on('message', (message) => {
const watchedFile = createTmpFile('', '.js', dir);
const configFile = createTmpFile(JSON.stringify({ watch: { 'watch-path': [dir] } }), '.json', dir);
- const args = [`--experimental-config-file=${configFile}`, file];
+ const args = [`--config-file=${configFile}`, file];
const { stderr, stdout } = await runWriteSucceed({ file, watchedFile, args });
assert.strictEqual(stderr, '');
@@ -924,7 +924,7 @@ process.on('message', (message) => {
const { stderr, stdout } = await runWriteSucceed({
file,
watchedFile: file,
- args: ['--experimental-default-config-file', file],
+ args: ['--config-file', file],
options: {
timeout: 10000,
cwd: dir,