From 914a3632b26a9a7cd3d048caf2fbe0be12ce8a27 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sat, 24 Jul 2021 19:34:41 +0200 Subject: [PATCH] module: disable CommonJS support if entry point is ESM Fixes: https://github.com/nodejs/node/issues/39353 --- lib/internal/modules/cjs/loader.js | 6 ++++- lib/internal/modules/esm/translators.js | 4 +++- lib/internal/modules/run_main.js | 23 ++++++++++++++++--- ...tax_in_entry_point_without_package.json.js | 1 + ...ax_in_entry_point_without_package.json.out | 3 +++ 5 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 test/message/esm_syntax_in_entry_point_without_package.json.js create mode 100644 test/message/esm_syntax_in_entry_point_without_package.json.out diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index 31ab3a8ee9c86f..79306a13b1aa43 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -63,15 +63,19 @@ const { StringPrototypeSlice, StringPrototypeSplit, StringPrototypeStartsWith, + Symbol, } = primordials; +const kContainsESMSyntax = Symbol('contains ESM syntax'); + // Map used to store CJS parsing data. const cjsParseCache = new SafeWeakMap(); // Set first due to cycle with ESM loader functions. module.exports = { wrapSafe, Module, toRealPath, readPackageScope, cjsParseCache, - get hasLoadedAnyUserCJSModule() { return hasLoadedAnyUserCJSModule; } + get hasLoadedAnyUserCJSModule() { return hasLoadedAnyUserCJSModule; }, + kContainsESMSyntax, }; const { NativeModule } = require('internal/bootstrap/loaders'); diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js index 6d295089e42c70..d04404576677bf 100644 --- a/lib/internal/modules/esm/translators.js +++ b/lib/internal/modules/esm/translators.js @@ -36,7 +36,8 @@ const { } = require('internal/modules/cjs/helpers'); const { Module: CJSModule, - cjsParseCache + cjsParseCache, + kContainsESMSyntax, } = require('internal/modules/cjs/loader'); const internalURLModule = require('internal/url'); const { defaultGetSource } = require( @@ -171,6 +172,7 @@ function enrichCJSError(err) { 'To load an ES module, set "type": "module" in the package.json or use ' + 'the .mjs extension.' ); + err[kContainsESMSyntax] = true; } } diff --git a/lib/internal/modules/run_main.js b/lib/internal/modules/run_main.js index b8238a1dd2c353..5b1404c2940104 100644 --- a/lib/internal/modules/run_main.js +++ b/lib/internal/modules/run_main.js @@ -4,7 +4,7 @@ const { StringPrototypeEndsWith, } = primordials; const CJSLoader = require('internal/modules/cjs/loader'); -const { Module, toRealPath, readPackageScope } = CJSLoader; +const { Module, kContainsESMSyntax, toRealPath, readPackageScope } = CJSLoader; const { getOptionValue } = require('internal/options'); const path = require('path'); @@ -75,8 +75,25 @@ function executeUserEntryPoint(main = process.argv[1]) { if (useESMLoader) { runMainESM(resolvedMain || main); } else { - // Module._load is the monkey-patchable CJS module loader. - Module._load(main, null, true); + try { + // Module._load is the monkey-patchable CJS module loader. + Module._load(main, null, true); + } catch (err) { + if (err?.[kContainsESMSyntax] && !readPackageScope(resolvedMain)) { + const { emitWarning } = require('internal/process/warning'); + emitWarning(`No package.json detected, attempting to load "${main}" with CommonJS support disabled.`); + const esmLoader = require('internal/process/esm_loader'); + esmLoader.ESMLoader._getFormat = (url, _, defaultGetFormat) => { + const defaultFormat = defaultGetFormat(url); + if (defaultFormat.format === 'commonjs') + defaultFormat.format = 'module'; + return defaultFormat; + }; + runMainESM(resolvedMain || main); + } else { + throw err; + } + } } } diff --git a/test/message/esm_syntax_in_entry_point_without_package.json.js b/test/message/esm_syntax_in_entry_point_without_package.json.js new file mode 100644 index 00000000000000..cb0ff5c3b541f6 --- /dev/null +++ b/test/message/esm_syntax_in_entry_point_without_package.json.js @@ -0,0 +1 @@ +export {}; diff --git a/test/message/esm_syntax_in_entry_point_without_package.json.out b/test/message/esm_syntax_in_entry_point_without_package.json.out new file mode 100644 index 00000000000000..ab2c536d6e1dc3 --- /dev/null +++ b/test/message/esm_syntax_in_entry_point_without_package.json.out @@ -0,0 +1,3 @@ +(node:*) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension. +(Use `node --trace-warnings ...` to show where the warning was created) +(node:*) Warning: No package.json detected, attempting to load "*/test/message/esm_syntax_in_entry_point_without_package.json.js" with CommonJS support disabled.