diff --git a/lib/repl.js b/lib/repl.js index 2871bab27d2712..c325a2e9fbe87f 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -324,10 +324,12 @@ function REPLServer(prompt, if (code === '\n') return cb(null); - let pwd; + let parentURL; try { const { pathToFileURL } = require('url'); - pwd = pathToFileURL(process.cwd()).href; + // Adding `/repl` prevents dynamic imports from loading relative + // to the parent of `process.cwd()`. + parentURL = pathToFileURL(path.join(process.cwd(), 'repl')).href; } catch { } while (true) { @@ -342,7 +344,7 @@ function REPLServer(prompt, filename: file, displayErrors: true, importModuleDynamically: experimentalModules ? async (specifier) => { - return asyncESM.ESMLoader.import(specifier, pwd); + return asyncESM.ESMLoader.import(specifier, parentURL); } : undefined }); } catch (e) { diff --git a/test/parallel/test-repl-import-referrer.js b/test/parallel/test-repl-import-referrer.js new file mode 100644 index 00000000000000..400015ced07f59 --- /dev/null +++ b/test/parallel/test-repl-import-referrer.js @@ -0,0 +1,29 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const cp = require('child_process'); +const fixtures = require('../common/fixtures'); + +const args = [ + '--interactive', + '--experimental-repl-await', + '--experimental-modules' +]; + +const opts = { cwd: fixtures.path('es-modules') }; +const child = cp.spawn(process.execPath, args, opts); + +let output = ''; +child.stdout.setEncoding('utf8'); +child.stdout.on('data', (data) => { + output += data; +}); + +child.on('exit', common.mustCall(() => { + const results = output.replace(/^> /mg, '').split('\n').slice(2); + assert.deepStrictEqual(results, ['[Module] { message: \'A message\' }', '']); +})); + +child.stdin.write('await import(\'./message.mjs\');\n'); +child.stdin.write('.exit'); +child.stdin.end();