diff --git a/lib/internal/process/execution.js b/lib/internal/process/execution.js index 10f9e52244cac2..7834ce9aa74e8c 100644 --- a/lib/internal/process/execution.js +++ b/lib/internal/process/execution.js @@ -83,7 +83,7 @@ function evalScript(name, body, breakFirstLine, print, shouldLoadESM = false) { if (getOptionValue('--experimental-detect-module') && getOptionValue('--input-type') === '' && getOptionValue('--experimental-default-type') === '' && - containsModuleSyntax(body, name)) { + containsModuleSyntax(body, name, null, 'no CJS variables')) { return evalModuleEntryPoint(body, print); } diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 6dbc127374492e..53062af31eea5a 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -1442,7 +1442,8 @@ static MaybeLocal CompileFunctionForCJSLoader(Environment* env, Local context, Local code, Local filename, - bool* cache_rejected) { + bool* cache_rejected, + bool is_cjs_scope) { Isolate* isolate = context->GetIsolate(); EscapableHandleScope scope(isolate); @@ -1494,7 +1495,10 @@ static MaybeLocal CompileFunctionForCJSLoader(Environment* env, options = ScriptCompiler::kConsumeCodeCache; } - std::vector> params = GetCJSParameters(env->isolate_data()); + std::vector> params; + if (is_cjs_scope) { + params = GetCJSParameters(env->isolate_data()); + } MaybeLocal maybe_fn = ScriptCompiler::CompileFunction( context, &source, @@ -1556,7 +1560,7 @@ static void CompileFunctionForCJSLoader( ShouldNotAbortOnUncaughtScope no_abort_scope(realm->env()); TryCatchScope try_catch(env); if (!CompileFunctionForCJSLoader( - env, context, code, filename, &cache_rejected) + env, context, code, filename, &cache_rejected, true) .ToLocal(&fn)) { CHECK(try_catch.HasCaught()); CHECK(!try_catch.HasTerminated()); @@ -1694,11 +1698,15 @@ static void ContainsModuleSyntax(const FunctionCallbackInfo& args) { CHECK(args[1]->IsString()); Local filename = args[1].As(); - // Argument 2: resource name (URL for ES module). + // Argument 3: resource name (URL for ES module). Local resource_name = filename; if (args[2]->IsString()) { resource_name = args[2].As(); } + // Argument 4: flag to indicate if CJS variables should not be in scope + // (they should be for normal CommonJS modules, but not for the + // CommonJS eval scope). + bool cjs_var = !args[3]->IsString(); bool cache_rejected = false; Local message; @@ -1707,7 +1715,7 @@ static void ContainsModuleSyntax(const FunctionCallbackInfo& args) { TryCatchScope try_catch(env); ShouldNotAbortOnUncaughtScope no_abort_scope(env); if (CompileFunctionForCJSLoader( - env, context, code, filename, &cache_rejected) + env, context, code, filename, &cache_rejected, cjs_var) .ToLocal(&fn)) { args.GetReturnValue().Set(false); return; diff --git a/test/es-module/test-esm-detect-ambiguous.mjs b/test/es-module/test-esm-detect-ambiguous.mjs index 9d5f6f06a1c66b..a58872e661c4f7 100644 --- a/test/es-module/test-esm-detect-ambiguous.mjs +++ b/test/es-module/test-esm-detect-ambiguous.mjs @@ -44,6 +44,19 @@ describe('--experimental-detect-module', { concurrency: !process.env.TEST_PARALL strictEqual(signal, null); }); + it('should not switch to module if code is parsable as script', async () => { + const { code, signal, stdout, stderr } = await spawnPromisified(process.execPath, [ + '--experimental-detect-module', + '--eval', + 'let __filename,__dirname,require,module,exports;this.a', + ]); + + strictEqual(stderr, ''); + strictEqual(stdout, ''); + strictEqual(code, 0); + strictEqual(signal, null); + }); + it('should be overridden by --experimental-default-type', async () => { const { code, signal, stdout, stderr } = await spawnPromisified(process.execPath, [ '--experimental-detect-module', @@ -393,3 +406,18 @@ describe('Wrapping a `require` of an ES module while using `--abort-on-uncaught- strictEqual(signal, null); }); }); + +describe('when working with Worker threads', () => { + it('should support sloppy scripts that declare CJS "global-like" variables', async () => { + const { code, signal, stdout, stderr } = await spawnPromisified(process.execPath, [ + '--experimental-detect-module', + '--eval', + 'new worker_threads.Worker("let __filename,__dirname,require,module,exports;this.a",{eval:true})', + ]); + + strictEqual(stderr, ''); + strictEqual(stdout, ''); + strictEqual(code, 0); + strictEqual(signal, null); + }); +});