Skip to content

Commit d4aa656

Browse files
coreyfarrelltargos
authored andcommitted
module: fix dynamic import from eval
This allows dynamic import to work from CLI `--eval` with or without `--input-type=module`. Fixes: #30591 PR-URL: #30624 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Yorkie Liu <[email protected]> Reviewed-By: Ben Coe <[email protected]>
1 parent 3557659 commit d4aa656

File tree

3 files changed

+44
-4
lines changed

3 files changed

+44
-4
lines changed

‎lib/internal/modules/esm/loader.js‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ const defaultResolve = require('internal/modules/esm/default_resolve');
2525
constcreateDynamicModule=require(
2626
'internal/modules/esm/create_dynamic_module');
2727
const{ translators }=require('internal/modules/esm/translators');
28-
const{ ModuleWrap }=internalBinding('module_wrap');
2928
const{ getOptionValue }=require('internal/options');
3029

3130
constdebug=require('internal/util/debuglog').debuglog('esm');
@@ -117,7 +116,17 @@ class Loader{
117116
source,
118117
url=pathToFileURL(`${process.cwd()}/[eval${++this.evalIndex}]`).href
119118
){
120-
constevalInstance=(url)=>newModuleWrap(url,undefined,source,0,0);
119+
constevalInstance=(url)=>{
120+
const{ ModuleWrap, callbackMap }=internalBinding('module_wrap');
121+
constmodule=newModuleWrap(url,undefined,source,0,0);
122+
callbackMap.set(module,{
123+
importModuleDynamically: (specifier,{ url })=>{
124+
returnthis.import(specifier,url);
125+
}
126+
});
127+
128+
returnmodule;
129+
};
121130
constjob=newModuleJob(this,url,evalInstance,false,false);
122131
this.moduleMap.set(url,job);
123132
const{ module, result }=awaitjob.run();

‎lib/internal/process/execution.js‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,27 +57,38 @@ function evalModule(source, print){
5757
functionevalScript(name,body,breakFirstLine,print){
5858
constCJSModule=require('internal/modules/cjs/loader').Module;
5959
const{ kVmBreakFirstLineSymbol }=require('internal/util');
60+
const{ pathToFileURL }=require('url');
6061

6162
constcwd=tryGetCwd();
6263
constorigModule=global.module;// Set e.g. when called from the REPL.
6364

6465
constmodule=newCJSModule(name);
6566
module.filename=path.join(cwd,name);
6667
module.paths=CJSModule._nodeModulePaths(cwd);
68+
6769
global.kVmBreakFirstLineSymbol=kVmBreakFirstLineSymbol;
70+
global.asyncESM=require('internal/process/esm_loader');
71+
72+
constbaseUrl=pathToFileURL(module.filename).href;
73+
6874
constscript=`
6975
global.__filename = ${JSONStringify(name)};
7076
global.exports = exports;
7177
global.module = module;
7278
global.__dirname = __dirname;
7379
global.require = require;
74-
const{kVmBreakFirstLineSymbol } = global;
80+
const{kVmBreakFirstLineSymbol, asyncESM } = global;
7581
delete global.kVmBreakFirstLineSymbol;
82+
delete global.asyncESM;
7683
return require("vm").runInThisContext(
7784
${JSONStringify(body)},{
7885
filename: ${JSONStringify(name)},
7986
displayErrors: true,
80-
[kVmBreakFirstLineSymbol]: ${!!breakFirstLine}
87+
[kVmBreakFirstLineSymbol]: ${!!breakFirstLine},
88+
async importModuleDynamically (specifier){
89+
const loader = await asyncESM.ESMLoader;
90+
return loader.import(specifier, ${JSONStringify(baseUrl)});
91+
}
8192
});\n`;
8293
constresult=module._compile(script,`${name}-wrapper`);
8394
if(print){

‎test/parallel/test-cli-eval.js‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,3 +283,23 @@ child.exec(
283283
assert.ifError(err);
284284
assert.strictEqual(stdout,'.mjs file\n');
285285
}));
286+
287+
288+
// Assert that packages can be dynamic imported initial cwd-relative with --eval
289+
child.exec(
290+
`${nodejs}${execOptions} `+
291+
'--eval "process.chdir(\'..\');'+
292+
'import(\'./test/fixtures/es-modules/mjs-file.mjs\')"',
293+
common.mustCall((err,stdout)=>{
294+
assert.ifError(err);
295+
assert.strictEqual(stdout,'.mjs file\n');
296+
}));
297+
298+
child.exec(
299+
`${nodejs} `+
300+
'--eval "process.chdir(\'..\');'+
301+
'import(\'./test/fixtures/es-modules/mjs-file.mjs\')"',
302+
common.mustCall((err,stdout)=>{
303+
assert.ifError(err);
304+
assert.strictEqual(stdout,'.mjs file\n');
305+
}));

0 commit comments

Comments
(0)