Skip to content

Commit 5d1230b

Browse files
marco-ippolitoaduh95
authored andcommitted
src: set default config as node.config.json
PR-URL: #57171 Backport-PR-URL: #57958 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Yagiz Nizipli <[email protected]>
1 parent e90583b commit 5d1230b

File tree

14 files changed

+146
-54
lines changed

14 files changed

+146
-54
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,7 @@ doc: $(NODE_EXE) doc-only ## Build Node.js, and then build the documentation wit
807807

808808
out/doc:
809809
mkdir -p $@
810-
cp doc/node_config_json_schema.json $@
810+
cp doc/node-config-schema.json $@
811811

812812
# If it's a source tarball, doc/api already contains the generated docs.
813813
# Just copy everything under doc/api over.

doc/api/cli.md

Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -909,61 +909,30 @@ flows within the application. As such, it is presently recommended to be sure
909909
your application behaviour is unaffected by this change before using it in
910910
production.
911911

912-
### `--experimental-default-type=type`
913-
914-
<!-- YAML
915-
added:
916-
- v21.0.0
917-
- v20.10.0
918-
- v18.19.0
919-
-->
920-
921-
> Stability: 1.0 - Early development
922-
923-
Define which module system, `module` or `commonjs`, to use for the following:
924-
925-
* String input provided via `--eval` or STDIN, if `--input-type` is unspecified.
926-
927-
* Files ending in `.js` or with no extension, if there is no `package.json` file
928-
present in the same folder or any parent folder.
929-
930-
* Files ending in `.js` or with no extension, if the nearest parent
931-
`package.json` field lacks a `"type"` field; unless the `package.json` folder
932-
or any parent folder is inside a `node_modules` folder.
933-
934-
In other words, `--experimental-default-type=module` flips all the places where
935-
Node.js currently defaults to CommonJS to instead default to ECMAScript modules,
936-
with the exception of folders and subfolders below `node_modules`, for backward
937-
compatibility.
938-
939-
Under `--experimental-default-type=module` and `--experimental-wasm-modules`,
940-
files with no extension will be treated as WebAssembly if they begin with the
941-
WebAssembly magic number (`\0asm`); otherwise they will be treated as ES module
942-
JavaScript.
943-
944-
### `--experimental-config-file`
912+
### `--experimental-config-file=config`
945913

946914
<!-- YAML
947915
added: REPLACEME
948916
-->
949917

950918
> Stability: 1.0 - Early development
951919
952-
Use this flag to specify a configuration file that will be loaded and parsed
953-
before the application starts.
920+
If present, Node.js will look for a
921+
configuration file at the specified path.
954922
Node.js will read the configuration file and apply the settings.
955923
The configuration file should be a JSON file
956924
with the following structure:
957925

926+
> \[!NOTE]
927+
> Replace `vX.Y.Z` in the `$schema` with the version of Node.js you are using.
928+
958929
```json
959930
{
960-
"$schema": "https://nodejs.org/dist/REPLACEME/docs/node_config_json_schema.json",
931+
"$schema": "https://nodejs.org/dist/vX.Y.Z/docs/node-config-schema.json",
961932
"nodeOptions": {
962-
"experimental-transform-types": true,
963933
"import": [
964-
"amaro/transform"
934+
"amaro/strip"
965935
],
966-
"disable-warning": "ExperimentalWarning",
967936
"watch-path": "src",
968937
"watch-preserve-output": true
969938
}
@@ -974,7 +943,7 @@ In the `nodeOptions` field, only flags that are allowed in [`NODE_OPTIONS`][] ar
974943
No-op flags are not supported.
975944
Not all V8 flags are currently supported.
976945

977-
It is possible to use the [official JSON schema](../node_config_json_schema.json)
946+
It is possible to use the [official JSON schema](../node-config-schema.json)
978947
to validate the configuration file, which may vary depending on the Node.js version.
979948
Each key in the configuration file corresponds to a flag that can be passed
980949
as a command-line argument. The value of the key is the value that would be
@@ -984,7 +953,7 @@ For example, the configuration file above is equivalent to
984953
the following command-line arguments:
985954

986955
```bash
987-
node --experimental-transform-types --import amaro/transform --disable-warning=ExperimentalWarning --watch-path=src --watch-preserve-output
956+
node --import amaro/strip --watch-path=src --watch-preserve-output
988957
```
989958

990959
The priority in configuration is as follows:
@@ -1006,6 +975,50 @@ unknown keys or keys that cannot used in `NODE_OPTIONS`.
1006975
Node.js will not sanitize or perform validation on the user-provided configuration,
1007976
so **NEVER** use untrusted configuration files.
1008977

978+
### `--experimental-default-config-file`
979+
980+
<!-- YAML
981+
added: REPLACEME
982+
-->
983+
984+
> Stability: 1.0 - Early development
985+
986+
If the `--experimental-default-config-file` flag is present, Node.js will look for a
987+
`node.config.json` file in the current working directory and load it as a
988+
as configuration file.
989+
990+
### `--experimental-default-type=type`
991+
992+
<!-- YAML
993+
added:
994+
- v21.0.0
995+
- v20.10.0
996+
- v18.19.0
997+
-->
998+
999+
> Stability: 1.0 - Early development
1000+
1001+
Define which module system, `module` or `commonjs`, to use for the following:
1002+
1003+
* String input provided via `--eval` or STDIN, if `--input-type` is unspecified.
1004+
1005+
* Files ending in `.js` or with no extension, if there is no `package.json` file
1006+
present in the same folder or any parent folder.
1007+
1008+
* Files ending in `.js` or with no extension, if the nearest parent
1009+
`package.json` field lacks a `"type"` field; unless the `package.json` folder
1010+
or any parent folder is inside a `node_modules` folder.
1011+
1012+
In other words, `--experimental-default-type=module` flips all the places where
1013+
Node.js currently defaults to CommonJS to instead default to ECMAScript modules,
1014+
with the exception of folders and subfolders below `node_modules`, for backward
1015+
compatibility.
1016+
1017+
Under `--experimental-default-type=module` and `--experimental-wasm-modules`,
1018+
files with no extension will be treated as WebAssembly if they begin with the
1019+
WebAssembly magic number (`\0asm`); otherwise they will be treated as ES module
1020+
JavaScript.
1021+
10091022
### `--experimental-eventsource`
10101023

10111024
<!-- YAML
File renamed without changes.

doc/node.1

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,10 @@ Interpret as either ES modules or CommonJS modules input via --eval or STDIN, wh
169169
.js or extensionless files whose nearest parent package.json lacks a "type" field, unless under node_modules.
170170
.
171171
.It Fl -experimental-config-file
172-
Enable support for experimental config file
172+
Specifies the configuration file to load.
173+
.
174+
.It Fl -experimental-default-config-file
175+
Enable support for automatically loading node.config.json.
173176
.
174177
.It Fl -experimental-import-meta-resolve
175178
Enable experimental ES modules support for import.meta.resolve().

lib/internal/process/pre_execution.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,8 @@ function setupSQLite() {
393393
}
394394

395395
function initializeConfigFileSupport() {
396-
if (getOptionValue('--experimental-config-file')) {
396+
if (getOptionValue('--experimental-default-config-file') ||
397+
getOptionValue('--experimental-config-file')) {
397398
emitExperimentalWarning('--experimental-config-file');
398399
}
399400
}

src/node_config_file.cc

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,32 @@ namespace node {
88

99
std::optional<std::string_view> ConfigReader::GetDataFromArgs(
1010
const std::vector<std::string>& args) {
11-
constexpr std::string_view flag = "--experimental-config-file";
11+
constexpr std::string_view flag_path = "--experimental-config-file";
12+
constexpr std::string_view default_file =
13+
"--experimental-default-config-file";
14+
15+
bool has_default_config_file = false;
1216

1317
for (auto it = args.begin(); it != args.end(); ++it) {
14-
if (*it == flag) {
18+
if (*it == flag_path) {
1519
// Case: "--experimental-config-file foo"
1620
if (auto next = std::next(it); next != args.end()) {
1721
return *next;
1822
}
19-
} else if (it->starts_with(flag)) {
23+
} else if (it->starts_with(flag_path)) {
2024
// Case: "--experimental-config-file=foo"
21-
if (it->size() > flag.size() && (*it)[flag.size()] == '=') {
22-
return it->substr(flag.size() + 1);
25+
if (it->size() > flag_path.size() && (*it)[flag_path.size()] == '=') {
26+
return it->substr(flag_path.size() + 1);
2327
}
28+
} else if (*it == default_file || it->starts_with(default_file)) {
29+
has_default_config_file = true;
2430
}
2531
}
2632

33+
if (has_default_config_file) {
34+
return "node.config.json";
35+
}
36+
2737
return std::nullopt;
2838
}
2939

src/node_options.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,10 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
690690
Implies("--env-file-if-exists", "[has_env_file_string]");
691691
AddOption("--experimental-config-file",
692692
"set config file from supplied file",
693-
&EnvironmentOptions::experimental_config_file);
693+
&EnvironmentOptions::experimental_config_file_path);
694+
AddOption("--experimental-default-config-file",
695+
"set config file from default config file",
696+
&EnvironmentOptions::experimental_default_config_file);
694697
AddOption("--test",
695698
"launch test runner on startup",
696699
&EnvironmentOptions::test_runner);

src/node_options.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,8 @@ class EnvironmentOptions : public Options {
257257

258258
bool report_exclude_env = false;
259259
bool report_exclude_network = false;
260-
std::string experimental_config_file;
260+
std::string experimental_config_file_path;
261+
bool experimental_default_config_file = false;
261262

262263
inline DebugOptions* get_debug_options() { return &debug_options_; }
263264
inline const DebugOptions& debug_options() const { return debug_options_; }
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"nodeOptions": {
3+
"max-http-header-size": 10
4+
}
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"nodeOptions": {
3+
"max-http-header-size": 20
4+
}
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"nodeOptions": {
3+
"max-http-header-size": 10
4+
}
5+
}

test/parallel/test-config-file.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ const { spawnPromisified } = require('../common');
44
const fixtures = require('../common/fixtures');
55
const { match, strictEqual } = require('node:assert');
66
const { test } = require('node:test');
7+
const { chmodSync, constants } = require('node:fs');
8+
const common = require('../common');
79

810
test('should handle non existing json', async () => {
911
const result = await spawnPromisified(process.execPath, [
@@ -305,3 +307,47 @@ test('broken value in node_options', async () => {
305307
strictEqual(result.stdout, '');
306308
strictEqual(result.code, 9);
307309
});
310+
311+
test('should use node.config.json as default', async () => {
312+
const result = await spawnPromisified(process.execPath, [
313+
'--no-warnings',
314+
'--experimental-default-config-file',
315+
'-p', 'http.maxHeaderSize',
316+
], {
317+
cwd: fixtures.path('rc/default'),
318+
});
319+
strictEqual(result.stderr, '');
320+
strictEqual(result.stdout, '10\n');
321+
strictEqual(result.code, 0);
322+
});
323+
324+
test('should override node.config.json when specificied', async () => {
325+
const result = await spawnPromisified(process.execPath, [
326+
'--no-warnings',
327+
'--experimental-default-config-file',
328+
'--experimental-config-file',
329+
fixtures.path('rc/default/override.json'),
330+
'-p', 'http.maxHeaderSize',
331+
], {
332+
cwd: fixtures.path('rc/default'),
333+
});
334+
strictEqual(result.stderr, '');
335+
strictEqual(result.stdout, '20\n');
336+
strictEqual(result.code, 0);
337+
});
338+
// Skip on windows because it doesn't support chmod changing read permissions
339+
test('should throw an error when the file is non readable', { skip: common.isWindows }, async () => {
340+
chmodSync(fixtures.path('rc/non-readable/node.config.json'), constants.O_RDONLY);
341+
const result = await spawnPromisified(process.execPath, [
342+
'--no-warnings',
343+
'--experimental-default-config-file',
344+
'-p', 'http.maxHeaderSize',
345+
], {
346+
cwd: fixtures.path('rc/non-readable'),
347+
});
348+
match(result.stderr, /Cannot read configuration from node\.config\.json: permission denied/);
349+
strictEqual(result.stdout, '');
350+
strictEqual(result.code, 9);
351+
chmodSync(fixtures.path('rc/non-readable/node.config.json'),
352+
constants.S_IRWXU | constants.S_IRWXG | constants.S_IRWXO);
353+
});

test/parallel/test-config-json-schema.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ if (!common.hasIntl) {
2424
const {
2525
generateConfigJsonSchema,
2626
} = require('internal/options');
27-
const schemaInDoc = require('../../doc/node_config_json_schema.json');
27+
const schemaInDoc = require('../../doc/node-config-schema.json');
2828
const assert = require('assert');
2929

3030
const schema = generateConfigJsonSchema();
@@ -35,6 +35,6 @@ const schema = generateConfigJsonSchema();
3535
// current JSON schema.
3636
// To regenerate the JSON schema, run:
3737
// out/Release/node --expose-internals tools/doc/generate-json-schema.mjs
38-
// And then run make doc to update the out/doc/node_config_json_schema.json file.
38+
// And then run make doc to update the out/doc/node-config-schema.json file.
3939
assert.strictEqual(JSON.stringify(schema), JSON.stringify(schemaInDoc), 'JSON schema is outdated.' +
4040
'Run `out/Release/node --expose-internals tools/doc/generate-json-schema.mjs` to update it.');

tools/doc/generate-json-schema.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ import internal from 'internal/options';
44
import { writeFileSync } from 'fs';
55

66
const schema = internal.generateConfigJsonSchema();
7-
writeFileSync('doc/node_config_json_schema.json', `${JSON.stringify(schema, null, 2)}\n`);
7+
writeFileSync('doc/node-config-schema.json', `${JSON.stringify(schema, null, 2)}\n`);

0 commit comments

Comments
 (0)