Skip to content

Commit 1db210a

Browse files
joyeecheungmarco-ippolito
authored andcommitted
module: check --experimental-require-module separately from detection
Previously we assumed if `--experimental-detect-module` is true, then `--experimental-require-module` is true, which isn't the case, as the two can be enabled/disabled separately. This patch fixes the checks so `--no-experimental-require-module` is still effective when `--experimental-detect-module` is enabled. Drive-by: make the assertion messages more informative and remove obsolete TODO about allowing TLA in entrypoints handled by require(esm). PR-URL: #55250 Backport-PR-URL: #56927 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Jacob Smith <jacob@frende.me> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Refs: #52697
1 parent ececd22 commit 1db210a

File tree

3 files changed

+34
-5
lines changed

3 files changed

+34
-5
lines changed

lib/internal/modules/cjs/loader.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,7 +1404,7 @@ function loadESMFromCJS(mod, filename) {
14041404
* @param {'commonjs'|undefined} format Intended format of the module.
14051405
*/
14061406
function wrapSafe(filename, content, cjsModuleInstance, format) {
1407-
assert(format !== 'module'); // ESM should be handled in loadESMFromCJS().
1407+
assert(format !== 'module', 'ESM should be handled in loadESMFromCJS()');
14081408
const hostDefinedOptionId = vm_dynamic_import_default_internal;
14091409
const importModuleDynamically = vm_dynamic_import_default_internal;
14101410
if (patched) {
@@ -1434,7 +1434,17 @@ function wrapSafe(filename, content, cjsModuleInstance, format) {
14341434
};
14351435
}
14361436

1437-
const shouldDetectModule = (format !== 'commonjs' && getOptionValue('--experimental-detect-module'));
1437+
let shouldDetectModule = false;
1438+
if (format !== 'commonjs') {
1439+
if (cjsModuleInstance?.[kIsMainSymbol]) {
1440+
// For entry points, format detection is used unless explicitly disabled.
1441+
shouldDetectModule = getOptionValue('--experimental-detect-module');
1442+
} else {
1443+
// For modules being loaded by `require()`, if require(esm) is disabled,
1444+
// don't try to reparse to detect format and just throw for ESM syntax.
1445+
shouldDetectModule = getOptionValue('--experimental-require-module');
1446+
}
1447+
}
14381448
const result = compileFunctionForCJSLoader(content, filename, false /* is_sea_main */, shouldDetectModule);
14391449

14401450
// Cache the source map for the module if present.
@@ -1471,8 +1481,6 @@ Module.prototype._compile = function(content, filename, format) {
14711481
}
14721482
}
14731483

1474-
// TODO(joyeecheung): when the module is the entry point, consider allowing TLA.
1475-
// Only modules being require()'d really need to avoid TLA.
14761484
if (format === 'module') {
14771485
// Pass the source into the .mjs extension handler indirectly through the cache.
14781486
this[kModuleSource] = content;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Flags: --no-experimental-require-module
2+
'use strict';
3+
4+
// Tests that --experimental-require-module is not implied by --experimental-detect-module
5+
// and is checked independently.
6+
require('../common');
7+
const assert = require('assert');
8+
9+
// Check that require() still throws SyntaxError for an ambiguous module that's detected to be ESM.
10+
// TODO(joyeecheung): now that --experimental-detect-module is unflagged, it makes more sense
11+
// to either throw ERR_REQUIRE_ESM for require() of detected ESM instead, or add a hint about the
12+
// use of require(esm) to the SyntaxError.
13+
14+
assert.throws(
15+
() => require('../fixtures/es-modules/loose.js'),
16+
{
17+
name: 'SyntaxError',
18+
message: /Unexpected token 'export'/
19+
});

test/fixtures/es-modules/loose.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
// This file can be run or imported only if `--experimental-default-type=module` is set.
1+
// This file can be run or imported only if `--experimental-default-type=module` is set
2+
// or `--experimental-detect-module` is not disabled. If it's loaded by
3+
// require(), then `--experimental-require-module` must not be disabled.
24
export default 'module';
35
console.log('executed');

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy