Skip to content

Commit

Permalink
repl: fix referrer for dynamic import
Browse files Browse the repository at this point in the history
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 <me@gus.host>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Ben Coe <bencoe@gmail.com>
  • Loading branch information
coreyfarrell authored and BethGriggs committed Feb 6, 2020
1 parent a81eae6 commit 106e5ce
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
8 changes: 5 additions & 3 deletions lib/repl.js
Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down
29 changes: 29 additions & 0 deletions 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();

0 comments on commit 106e5ce

Please sign in to comment.