Skip to content

Commit b91d22c

Browse files
coreyfarrelltargos
authored andcommitted
repl: fix referrer for dynamic import
The ESM loader does not accept a directory as the referrer, it requires a path within the directory. Add `/repl` to ensure relative dynamic imports can succeed. Fixes: #19570 PR-URL: #30609 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ben Coe <[email protected]>
1 parent 6257408 commit b91d22c

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

lib/repl.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,10 +332,12 @@ function REPLServer(prompt,
332332
if (code === '\n')
333333
return cb(null);
334334

335-
let pwd;
335+
let parentURL;
336336
try {
337337
const { pathToFileURL } = require('url');
338-
pwd = pathToFileURL(process.cwd()).href;
338+
// Adding `/repl` prevents dynamic imports from loading relative
339+
// to the parent of `process.cwd()`.
340+
parentURL = pathToFileURL(path.join(process.cwd(), 'repl')).href;
339341
} catch {
340342
}
341343
while (true) {
@@ -350,7 +352,7 @@ function REPLServer(prompt,
350352
filename: file,
351353
displayErrors: true,
352354
importModuleDynamically: async (specifier) => {
353-
return asyncESM.ESMLoader.import(specifier, pwd);
355+
return asyncESM.ESMLoader.import(specifier, parentURL);
354356
}
355357
});
356358
} catch (e) {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const cp = require('child_process');
5+
const fixtures = require('../common/fixtures');
6+
7+
const args = ['--interactive', '--experimental-repl-await'];
8+
const opts = { cwd: fixtures.path('es-modules') };
9+
const child = cp.spawn(process.execPath, args, opts);
10+
11+
let output = '';
12+
child.stdout.setEncoding('utf8');
13+
child.stdout.on('data', (data) => {
14+
output += data;
15+
});
16+
17+
child.on('exit', common.mustCall(() => {
18+
const results = output.replace(/^> /mg, '').split('\n').slice(2);
19+
assert.deepStrictEqual(results, ['[Module] { message: \'A message\' }', '']);
20+
}));
21+
22+
child.stdin.write('await import(\'./message.mjs\');\n');
23+
child.stdin.write('.exit');
24+
child.stdin.end();

0 commit comments

Comments
 (0)