Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions doc/api/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -1014,7 +1014,7 @@ added:

Enable experimental import support for `.node` addons.

### `--experimental-config-file=config`
### `--experimental-config-file=path`, `--experimental-config-file`

<!-- YAML
added:
Expand All @@ -1025,6 +1025,10 @@ added:
> Stability: 1.0 - Early development

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.
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.
Expand Down Expand Up @@ -1131,9 +1135,10 @@ added:

> Stability: 1.0 - Early development

If the `--experimental-default-config-file` flag is present, Node.js will look for a
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
as configuration file.
configuration file.

### `--experimental-eventsource`

Expand Down
2 changes: 1 addition & 1 deletion doc/api/test.md
Original file line number Diff line number Diff line change
Expand Up @@ -4131,7 +4131,7 @@ Can be used to abort test subtasks when the test has been aborted.
[`suite()`]: #suitename-options-fn
[`test()`]: #testname-options-fn
[code coverage]: #collecting-code-coverage
[configuration files]: cli.md#--experimental-config-fileconfig
[configuration files]: cli.md#--experimental-config-filepath---experimental-config-file
[describe options]: #describename-options-fn
[it options]: #testname-options-fn
[running tests from the command line]: #running-tests-from-the-command-line
Expand Down
9 changes: 6 additions & 3 deletions doc/node.1
Original file line number Diff line number Diff line change
Expand Up @@ -602,8 +602,10 @@ It is possible to run code containing inline types unless the
.It Fl -experimental-addon-modules
Enable experimental import support for \fB.node\fR addons.
.
.It Fl -experimental-config-file Ns = Ns Ar config
.It Fl -experimental-config-file= Ns Ar config , Fl -experimental-config-file , Fl -experimental-default-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.
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.
Expand Down Expand Up @@ -689,9 +691,10 @@ Node.js will not sanitize or perform validation on the user-provided configurati
so \fBNEVER\fR use untrusted configuration files.
.
.It Fl -experimental-default-config-file
If the \fB--experimental-default-config-file\fR flag is present, Node.js will look for a
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
as configuration file.
configuration file.
.
.It Fl -experimental-eventsource
Enable exposition of EventSource Web API on the global scope.
Expand Down
3 changes: 2 additions & 1 deletion lib/internal/process/pre_execution.js
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,8 @@ function setupSQLite() {

function initializeConfigFileSupport() {
if (getOptionValue('--experimental-default-config-file') ||
getOptionValue('--experimental-config-file')) {
getOptionValue('--experimental-config-file') ||
getOptionValue('--experimental-config-file=')) {
emitExperimentalWarning('--experimental-config-file');
}
}
Expand Down
13 changes: 11 additions & 2 deletions src/node_config_file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,22 @@ std::optional<std::string_view> ConfigReader::GetDataFromArgs(
for (auto it = args.begin(); it != args.end(); ++it) {
if (*it == flag_path) {
// Case: "--experimental-config-file foo"
if (auto next = std::next(it); next != args.end()) {
if (auto next = std::next(it);
next != args.end() && !next->starts_with("-")) {
return *next;
}
// Case: "--experimental-config-file" without argument, use default
has_default_config_file = true;
} else if (it->starts_with(flag_path)) {
// Case: "--experimental-config-file=foo"
if (it->size() > flag_path.size() && (*it)[flag_path.size()] == '=') {
return std::string_view(*it).substr(flag_path.size() + 1);
std::string_view value =
std::string_view(*it).substr(flag_path.size() + 1);
if (value.empty()) {
has_default_config_file = true;
} else {
return value;
}
}
} else if (*it == default_file || it->starts_with(default_file)) {
has_default_config_file = true;
Expand Down
14 changes: 9 additions & 5 deletions src/node_options.cc
Original file line number Diff line number Diff line change
Expand Up @@ -868,12 +868,16 @@ 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("--experimental-config-file=",
"set config file from supplied file",
&EnvironmentOptions::experimental_config_file_path);
AddOption("--experimental-default-config-file",
"set config file from default config file",
&EnvironmentOptions::experimental_default_config_file);
&EnvironmentOptions::experimental_config_file_path,
kDisallowedInEnvvar);
AddOption("--experimental-config-file",
"set default config file",
&EnvironmentOptions::experimental_default_config_file,
kDisallowedInEnvvar);
AddAlias("--experimental-config-file <arg>", "--experimental-config-file=");
AddAlias("--experimental-default-config-file", "--experimental-config-file");
AddOption("--test",
"launch test runner on startup",
&EnvironmentOptions::test_runner,
Expand Down
1 change: 1 addition & 0 deletions test/parallel/test-cli-node-options-docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
// CLI options
if (!isV8Option && !hasTrueAsDefaultValue) {
if (!new RegExp(`###.*\`${RegExp.escape(envVar)}[[=\\s\\b\`]`).test(cliText)) {
assert.fail(`Should have option ${envVar} documented`);

Check failure on line 66 in test/parallel/test-cli-node-options-docs.js

View workflow job for this annotation

GitHub Actions / test-macOS

--- stderr --- node:assert:173 throw err; ^ AssertionError [ERR_ASSERTION]: Should have option --experimental-config-file= documented at Object.<anonymous> (/Users/runner/work/node/node/node/test/parallel/test-cli-node-options-docs.js:66:14) at Module._compile (node:internal/modules/cjs/loader:1809:14) at Object..js (node:internal/modules/cjs/loader:1940:10) at Module.load (node:internal/modules/cjs/loader:1530:32) at Module._load (node:internal/modules/cjs/loader:1332:12) at wrapModuleLoad (node:internal/modules/cjs/loader:255:19) at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:154:5) at node:internal/main/run_main_module:33:47 { generatedMessage: false, code: 'ERR_ASSERTION', actual: undefined, expected: undefined, operator: 'fail', diff: 'simple' } Node.js v26.0.0-pre Command: out/Release/node /Users/runner/work/node/node/node/test/parallel/test-cli-node-options-docs.js

Check failure on line 66 in test/parallel/test-cli-node-options-docs.js

View workflow job for this annotation

GitHub Actions / test-linux (ubuntu-24.04)

--- stderr --- node:assert:173 throw err; ^ AssertionError [ERR_ASSERTION]: Should have option --experimental-config-file= documented at Object.<anonymous> (/home/runner/work/node/node/node/test/parallel/test-cli-node-options-docs.js:66:14) at Module._compile (node:internal/modules/cjs/loader:1809:14) at Object..js (node:internal/modules/cjs/loader:1940:10) at Module.load (node:internal/modules/cjs/loader:1530:32) at Module._load (node:internal/modules/cjs/loader:1332:12) at wrapModuleLoad (node:internal/modules/cjs/loader:255:19) at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:154:5) at node:internal/main/run_main_module:33:47 { generatedMessage: false, code: 'ERR_ASSERTION', actual: undefined, expected: undefined, operator: 'fail', diff: 'simple' } Node.js v26.0.0-pre Command: out/Release/node /home/runner/work/node/node/node/test/parallel/test-cli-node-options-docs.js

Check failure on line 66 in test/parallel/test-cli-node-options-docs.js

View workflow job for this annotation

GitHub Actions / test-linux (ubuntu-24.04-arm)

--- stderr --- node:assert:173 throw err; ^ AssertionError [ERR_ASSERTION]: Should have option --experimental-config-file= documented at Object.<anonymous> (/home/runner/work/node/node/node/test/parallel/test-cli-node-options-docs.js:66:14) at Module._compile (node:internal/modules/cjs/loader:1809:14) at Object..js (node:internal/modules/cjs/loader:1940:10) at Module.load (node:internal/modules/cjs/loader:1530:32) at Module._load (node:internal/modules/cjs/loader:1332:12) at wrapModuleLoad (node:internal/modules/cjs/loader:255:19) at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:154:5) at node:internal/main/run_main_module:33:47 { generatedMessage: false, code: 'ERR_ASSERTION', actual: undefined, expected: undefined, operator: 'fail', diff: 'simple' } Node.js v26.0.0-pre Command: out/Release/node /home/runner/work/node/node/node/test/parallel/test-cli-node-options-docs.js

Check failure on line 66 in test/parallel/test-cli-node-options-docs.js

View workflow job for this annotation

GitHub Actions / x86_64-linux: with shared libraries

--- stderr --- node:assert:173 throw err; ^ AssertionError [ERR_ASSERTION]: Should have option --experimental-config-file= documented at Object.<anonymous> (/home/runner/work/_temp/node-v26.0.0-nightly2026-02-01de57fd605e-slim/test/parallel/test-cli-node-options-docs.js:66:14) at Module._compile (node:internal/modules/cjs/loader:1809:14) at Object..js (node:internal/modules/cjs/loader:1940:10) at Module.load (node:internal/modules/cjs/loader:1530:32) at Module._load (node:internal/modules/cjs/loader:1332:12) at wrapModuleLoad (node:internal/modules/cjs/loader:255:19) at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:154:5) at node:internal/main/run_main_module:33:47 { generatedMessage: false, code: 'ERR_ASSERTION', actual: undefined, expected: undefined, operator: 'fail', diff: 'simple' } Node.js v26.0.0-pre Command: out/Release/node /home/runner/work/_temp/node-v26.0.0-nightly2026-02-01de57fd605e-slim/test/parallel/test-cli-node-options-docs.js

Check failure on line 66 in test/parallel/test-cli-node-options-docs.js

View workflow job for this annotation

GitHub Actions / aarch64-linux: with shared libraries

--- stderr --- node:assert:173 throw err; ^ AssertionError [ERR_ASSERTION]: Should have option --experimental-config-file= documented at Object.<anonymous> (/home/runner/work/_temp/node-v26.0.0-nightly2026-02-01de57fd605e-slim/test/parallel/test-cli-node-options-docs.js:66:14) at Module._compile (node:internal/modules/cjs/loader:1809:14) at Object..js (node:internal/modules/cjs/loader:1940:10) at Module.load (node:internal/modules/cjs/loader:1530:32) at Module._load (node:internal/modules/cjs/loader:1332:12) at wrapModuleLoad (node:internal/modules/cjs/loader:255:19) at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:154:5) at node:internal/main/run_main_module:33:47 { generatedMessage: false, code: 'ERR_ASSERTION', actual: undefined, expected: undefined, operator: 'fail', diff: 'simple' } Node.js v26.0.0-pre Command: out/Release/node /home/runner/work/_temp/node-v26.0.0-nightly2026-02-01de57fd605e-slim/test/parallel/test-cli-node-options-docs.js
} else {
manPagesOptions.delete(envVar.slice(1));
}
Expand Down Expand Up @@ -122,5 +122,6 @@

// 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]}`);
28 changes: 28 additions & 0 deletions test/parallel/test-config-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,34 @@ 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',
onlyIfNodeOptionsSupport, async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
'--experimental-config-file',
'-p', 'http.maxHeaderSize',
], {
cwd: fixtures.path('rc/default'),
});
assert.strictEqual(result.stderr, '');
assert.strictEqual(result.stdout, '10\n');
assert.strictEqual(result.code, 0);
});

test('should use node.config.json when --experimental-config-file= has empty argument',
onlyIfNodeOptionsSupport, async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
'--experimental-config-file=',
'-p', 'http.maxHeaderSize',
], {
cwd: fixtures.path('rc/default'),
});
assert.strictEqual(result.stderr, '');
assert.strictEqual(result.stdout, '10\n');
assert.strictEqual(result.code, 0);
});

test('should override node.config.json when specificied', onlyIfNodeOptionsSupport, async () => {
const result = await spawnPromisified(process.execPath, [
'--no-warnings',
Expand Down
2 changes: 0 additions & 2 deletions test/parallel/test-runner-flag-propagation.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ 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-default-config-file', '', false],
Comment on lines -18 to -19
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we removing those entries in the test?

['--env-file', '.env', '.env'],
['--env-file-if-exists', '.env', '.env'],
['--test-concurrency', '2', '2'],
Expand Down
Loading