Skip to content

Commit 8af1505

Browse files
GeoffreyBoothtargos
authored andcommitted
module: unflag detect-module
PR-URL: #53619 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]>
1 parent 0f1fe63 commit 8af1505

20 files changed

+120
-130
lines changed

doc/api/cli.md

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -902,39 +902,6 @@ files with no extension will be treated as WebAssembly if they begin with the
902902
WebAssembly magic number (`\0asm`); otherwise they will be treated as ES module
903903
JavaScript.
904904

905-
### `--experimental-detect-module`
906-
907-
<!-- YAML
908-
added:
909-
- v21.1.0
910-
- v20.10.0
911-
-->
912-
913-
> Stability: 1.1 - Active development
914-
915-
Node.js will inspect the source code of ambiguous input to determine whether it
916-
contains ES module syntax; if such syntax is detected, the input will be treated
917-
as an ES module.
918-
919-
Ambiguous input is defined as:
920-
921-
* Files with a `.js` extension or no extension; and either no controlling
922-
`package.json` file or one that lacks a `type` field; and
923-
`--experimental-default-type` is not specified.
924-
* String input (`--eval` or STDIN) when neither `--input-type` nor
925-
`--experimental-default-type` are specified.
926-
927-
ES module syntax is defined as syntax that would throw when evaluated as
928-
CommonJS. This includes the following:
929-
930-
* `import` statements (but _not_ `import()` expressions, which are valid in
931-
CommonJS).
932-
* `export` statements.
933-
* `import.meta` references.
934-
* `await` at the top level of a module.
935-
* Lexical redeclarations of the CommonJS wrapper variables (`require`, `module`,
936-
`exports`, `__dirname`, `__filename`).
937-
938905
### `--experimental-eventsource`
939906

940907
<!-- YAML
@@ -1582,6 +1549,21 @@ added: v0.8.0
15821549

15831550
Silence deprecation warnings.
15841551

1552+
### `--no-experimental-detect-module`
1553+
1554+
<!-- YAML
1555+
added:
1556+
- v21.1.0
1557+
- v20.10.0
1558+
changes:
1559+
- version:
1560+
- REPLACEME
1561+
pr-url: https://github.com/nodejs/node/pull/53619
1562+
description: Syntax detection is enabled by default.
1563+
-->
1564+
1565+
Disable using [syntax detection][] to determine module type.
1566+
15851567
### `--no-experimental-fetch`
15861568

15871569
<!-- YAML
@@ -3545,6 +3527,7 @@ node --stack-trace-limit=12 -p -e "Error.stackTraceLimit" # prints 12
35453527
[semi-space]: https://www.memorymanagement.org/glossary/s.html#semi.space
35463528
[single executable application]: single-executable-applications.md
35473529
[snapshot testing]: test.md#snapshot-testing
3530+
[syntax detection]: packages.md#syntax-detection
35483531
[test reporters]: test.md#test-reporters
35493532
[timezone IDs]: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
35503533
[tracking issue for user-land snapshots]: https://github.com/nodejs/node/issues/44014

doc/api/esm.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,8 +1082,7 @@ _isImports_, _conditions_)
10821082
> 10. If _url_ ends in _".js"_, then
10831083
> 1. If _packageType_ is not **null**, then
10841084
> 1. Return _packageType_.
1085-
> 2. If `--experimental-detect-module` is enabled and the result of
1086-
> **DETECT\_MODULE\_SYNTAX**(_source_) is true, then
1085+
> 2. If the result of **DETECT\_MODULE\_SYNTAX**(_source_) is true, then
10871086
> 1. Return _"module"_.
10881087
> 3. Return _"commonjs"_.
10891088
> 11. If _url_ does not have any extension, then
@@ -1093,8 +1092,7 @@ _isImports_, _conditions_)
10931092
> 1. Return _"wasm"_.
10941093
> 2. If _packageType_ is not **null**, then
10951094
> 1. Return _packageType_.
1096-
> 3. If `--experimental-detect-module` is enabled and the source of
1097-
> module contains static import or export syntax, then
1095+
> 3. If the result of **DETECT\_MODULE\_SYNTAX**(_source_) is true, then
10981096
> 1. Return _"module"_.
10991097
> 4. Return _"commonjs"_.
11001098
> 12. Return **undefined** (will throw during load phase).

doc/api/modules.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ loaded by `require()` meets the following requirements:
185185
1. The file has a `.mjs` extension.
186186
2. The file has a `.js` extension, and the closest `package.json` contains `"type": "module"`
187187
3. The file has a `.js` extension, the closest `package.json` does not contain
188-
`"type": "commonjs"`, and `--experimental-detect-module` is enabled.
188+
`"type": "commonjs"`, and the module contains ES module syntax.
189189

190190
`require()` will load the requested module as an ES Module, and return
191191
the module namespace object. In this case it is similar to dynamic
@@ -272,7 +272,7 @@ require(X) from module at path Y
272272
273273
MAYBE_DETECT_AND_LOAD(X)
274274
1. If X parses as a CommonJS module, load X as a CommonJS module. STOP.
275-
2. Else, if `--experimental-require-module` and `--experimental-detect-module` are
275+
2. Else, if `--experimental-require-module` is
276276
enabled, and the source code of X can be parsed as ECMAScript module using
277277
<a href="esm.md#resolver-algorithm-specification">DETECT_MODULE_SYNTAX defined in
278278
the ESM resolver</a>,

doc/api/packages.md

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,14 @@ expressions:
6969
* Strings passed in as an argument to `--eval`, or piped to `node` via `STDIN`,
7070
with the flag `--input-type=module`.
7171

72-
* When using [`--experimental-detect-module`][], code containing syntax only
73-
successfully parsed as [ES modules][], such as `import` or `export`
74-
statements or `import.meta`, having no explicit marker of how it should be
75-
interpreted. Explicit markers are `.mjs` or `.cjs` extensions, `package.json`
76-
`"type"` fields with either `"module"` or `"commonjs"` values, or
77-
`--input-type` or `--experimental-default-type` flags. Dynamic `import()`
78-
expressions are supported in either CommonJS or ES modules and would not
79-
cause a file to be treated as an ES module.
72+
* Code containing syntax only successfully parsed as [ES modules][], such as
73+
`import` or `export` statements or `import.meta`, with no explicit marker of
74+
how it should be interpreted. Explicit markers are `.mjs` or `.cjs`
75+
extensions, `package.json` `"type"` fields with either `"module"` or
76+
`"commonjs"` values, or `--input-type` or `--experimental-default-type` flags.
77+
Dynamic `import()` expressions are supported in either CommonJS or ES modules
78+
and would not force a file to be treated as an ES module. See
79+
[Syntax detection][].
8080

8181
Node.js will treat the following as [CommonJS][] when passed to `node` as the
8282
initial input, or when referenced by `import` statements or `import()`
@@ -115,6 +115,44 @@ package in case the default type of Node.js ever changes, and it will also make
115115
things easier for build tools and loaders to determine how the files in the
116116
package should be interpreted.
117117

118+
### Syntax detection
119+
120+
<!-- YAML
121+
added:
122+
- v21.1.0
123+
- v20.10.0
124+
changes:
125+
- version:
126+
- REPLACEME
127+
pr-url: https://github.com/nodejs/node/pull/53619
128+
description: Syntax detection is enabled by default.
129+
-->
130+
131+
> Stability: 1.2 - Release candidate
132+
133+
Node.js will inspect the source code of ambiguous input to determine whether it
134+
contains ES module syntax; if such syntax is detected, the input will be treated
135+
as an ES module.
136+
137+
Ambiguous input is defined as:
138+
139+
* Files with a `.js` extension or no extension; and either no controlling
140+
`package.json` file or one that lacks a `type` field; and
141+
`--experimental-default-type` is not specified.
142+
* String input (`--eval` or STDIN) when neither `--input-type` nor
143+
`--experimental-default-type` are specified.
144+
145+
ES module syntax is defined as syntax that would throw when evaluated as
146+
CommonJS. This includes the following:
147+
148+
* `import` statements (but _not_ `import()` expressions, which are valid in
149+
CommonJS).
150+
* `export` statements.
151+
* `import.meta` references.
152+
* `await` at the top level of a module.
153+
* Lexical redeclarations of the CommonJS wrapper variables (`require`, `module`,
154+
`exports`, `__dirname`, `__filename`).
155+
118156
### Modules loaders
119157

120158
Node.js has two systems for resolving a specifier and loading modules.
@@ -1355,6 +1393,7 @@ This field defines [subpath imports][] for the current package.
13551393
[ES modules]: esm.md
13561394
[Node.js documentation for this section]: https://github.com/nodejs/node/blob/HEAD/doc/api/packages.md#conditions-definitions
13571395
[Runtime Keys]: https://runtime-keys.proposal.wintercg.org/
1396+
[Syntax detection]: #syntax-detection
13581397
[WinterCG]: https://wintercg.org/
13591398
[`"exports"`]: #exports
13601399
[`"imports"`]: #imports
@@ -1364,7 +1403,6 @@ This field defines [subpath imports][] for the current package.
13641403
[`"type"`]: #type
13651404
[`--conditions` / `-C` flag]: #resolving-user-conditions
13661405
[`--experimental-default-type`]: cli.md#--experimental-default-typetype
1367-
[`--experimental-detect-module`]: cli.md#--experimental-detect-module
13681406
[`--no-addons` flag]: cli.md#--no-addons
13691407
[`ERR_PACKAGE_PATH_NOT_EXPORTED`]: errors.md#err_package_path_not_exported
13701408
[`esm`]: https://github.com/standard-things/esm#readme

lib/internal/main/check_syntax.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,23 +57,23 @@ function loadESMIfNeeded(cb) {
5757
}
5858

5959
async function checkSyntax(source, filename) {
60-
let isModule = true;
60+
let format;
6161
if (filename === '[stdin]' || filename === '[eval]') {
62-
isModule = getOptionValue('--input-type') === 'module' ||
63-
(getOptionValue('--experimental-default-type') === 'module' && getOptionValue('--input-type') !== 'commonjs');
62+
format = (getOptionValue('--input-type') === 'module' ||
63+
(getOptionValue('--experimental-default-type') === 'module' && getOptionValue('--input-type') !== 'commonjs')) ?
64+
'module' : 'commonjs';
6465
} else {
6566
const { defaultResolve } = require('internal/modules/esm/resolve');
6667
const { defaultGetFormat } = require('internal/modules/esm/get_format');
6768
const { url } = await defaultResolve(pathToFileURL(filename).toString());
68-
const format = await defaultGetFormat(new URL(url));
69-
isModule = format === 'module';
69+
format = await defaultGetFormat(new URL(url));
7070
}
7171

72-
if (isModule) {
72+
if (format === 'module') {
7373
const { ModuleWrap } = internalBinding('module_wrap');
7474
new ModuleWrap(filename, undefined, source, 0, 0);
7575
return;
7676
}
7777

78-
wrapSafe(filename, source, undefined, 'commonjs');
78+
wrapSafe(filename, source, undefined, format);
7979
}

lib/internal/modules/run_main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ function runEntryPointWithESMLoader(callback) {
142142
* by `require('module')`) even when the entry point is ESM.
143143
* This monkey-patchable code is bypassed under `--experimental-default-type=module`.
144144
* Because of backwards compatibility, this function is exposed publicly via `import { runMain } from 'node:module'`.
145-
* When `--experimental-detect-module` is passed, this function will attempt to run ambiguous (no explicit extension, no
145+
* Because of module detection, this function will attempt to run ambiguous (no explicit extension, no
146146
* `package.json` type field) entry points as CommonJS first; under certain conditions, it will retry running as ESM.
147147
* @param {string} main - First positional CLI argument, such as `'entry.js'` from `node entry.js`
148148
*/

src/node_options.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,8 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
356356
"when ambiguous modules fail to evaluate because they contain "
357357
"ES module syntax, try again to evaluate them as ES modules",
358358
&EnvironmentOptions::detect_module,
359-
kAllowedInEnvvar);
359+
kAllowedInEnvvar,
360+
true);
360361
AddOption("--experimental-print-required-tla",
361362
"Print pending top-level await. If --experimental-require-module "
362363
"is true, evaluate asynchronous graphs loaded by `require()` but "

src/node_options.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class EnvironmentOptions : public Options {
110110
public:
111111
bool abort_on_uncaught_exception = false;
112112
std::vector<std::string> conditions;
113-
bool detect_module = false;
113+
bool detect_module = true;
114114
bool print_required_tla = false;
115115
bool require_module = false;
116116
std::string dns_result_order;

test/es-module/test-esm-cjs-exports.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@ describe('ESM: importing CJS', { concurrency: !process.env.TEST_PARALLEL }, () =
2121
const invalidEntry = fixtures.path('/es-modules/cjs-exports-invalid.mjs');
2222
const { code, signal, stderr } = await spawnPromisified(execPath, [invalidEntry]);
2323

24+
assert.match(stderr, /SyntaxError: The requested module '\.\/invalid-cjs\.js' does not provide an export named 'default'/);
2425
assert.strictEqual(code, 1);
2526
assert.strictEqual(signal, null);
26-
assert.ok(stderr.includes('Warning: To load an ES module'));
27-
assert.ok(stderr.includes('Unexpected token \'export\''));
2827
});
2928
});

0 commit comments

Comments
 (0)