Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 84fe811

Browse filesBrowse files
hemanthRafaelGSS
authored andcommitted
repl: display dynamic import variant in static import error messages
Enhance the REPL message for static import error message. ``` > import {foo, bar} from 'moo'; import {foo, bar} from 'moo'; ^^^^^^ Uncaught: SyntaxError: .* dynamic import: const {foo,bar} = await import('moo'); ``` PR-URL: #48129 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent e60b6de commit 84fe811
Copy full SHA for 84fe811

File tree

Expand file treeCollapse file tree

2 files changed

+95
-2
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+95
-2
lines changed
Open diff view settings
Collapse file

‎lib/repl.js‎

Copy file name to clipboardExpand all lines: lib/repl.js
+27-1Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
'use strict';
4444

4545
const {
46+
ArrayPrototypeAt,
4647
ArrayPrototypeFilter,
4748
ArrayPrototypeFindIndex,
4849
ArrayPrototypeForEach,
@@ -62,6 +63,7 @@ const {
6263
Boolean,
6364
Error,
6465
FunctionPrototypeBind,
66+
JSONStringify,
6567
MathMaxApply,
6668
NumberIsNaN,
6769
NumberParseFloat,
@@ -104,7 +106,9 @@ const {
104106
const {
105107
isIdentifierStart,
106108
isIdentifierChar,
109+
parse: acornParse,
107110
} = require('internal/deps/acorn/acorn/dist/acorn');
111+
const acornWalk = require('internal/deps/acorn/acorn-walk/dist/walk');
108112
const {
109113
decorateErrorStack,
110114
isError,
@@ -223,6 +227,28 @@ module.paths = CJSModule._nodeModulePaths(module.filename);
223227
const writer = (obj) => inspect(obj, writer.options);
224228
writer.options = { ...inspect.defaultOptions, showProxy: true };
225229

230+
// Converts static import statement to dynamic import statement
231+
const toDynamicImport = (codeLine) => {
232+
let dynamicImportStatement = '';
233+
const ast = acornParse(codeLine, { __proto__: null, sourceType: 'module', ecmaVersion: 'latest' });
234+
acornWalk.ancestor(ast, {
235+
ImportDeclaration(node) {
236+
const awaitDynamicImport = `await import(${JSONStringify(node.source.value)});`;
237+
if (node.specifiers.length === 0) {
238+
dynamicImportStatement += awaitDynamicImport;
239+
} else if (node.specifiers.length === 1 && node.specifiers[0].type === 'ImportNamespaceSpecifier') {
240+
dynamicImportStatement += `const ${node.specifiers[0].local.name} = ${awaitDynamicImport}`;
241+
} else {
242+
const importNames = ArrayPrototypeJoin(ArrayPrototypeMap(node.specifiers, ({ local, imported }) =>
243+
(local.name === imported?.name ? local.name : `${imported?.name ?? 'default'}: ${local.name}`),
244+
), ', ');
245+
dynamicImportStatement += `const { ${importNames} } = ${awaitDynamicImport}`;
246+
}
247+
},
248+
});
249+
return dynamicImportStatement;
250+
};
251+
226252
function REPLServer(prompt,
227253
stream,
228254
eval_,
@@ -684,7 +710,7 @@ function REPLServer(prompt,
684710
'module';
685711
if (StringPrototypeIncludes(e.message, importErrorStr)) {
686712
e.message = 'Cannot use import statement inside the Node.js ' +
687-
'REPL, alternatively use dynamic import';
713+
'REPL, alternatively use dynamic import: ' + toDynamicImport(ArrayPrototypeAt(self.lines, -1));
688714
e.stack = SideEffectFreeRegExpPrototypeSymbolReplace(
689715
/SyntaxError:.*\n/,
690716
e.stack,
Collapse file

‎test/parallel/test-repl.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-repl.js
+68-1Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,74 @@ const tcpTests = [
818818
kArrow,
819819
'',
820820
'Uncaught:',
821-
/^SyntaxError: .* dynamic import/,
821+
'SyntaxError: Cannot use import statement inside the Node.js REPL, \
822+
alternatively use dynamic import: const { default: comeOn } = await import("fhqwhgads");',
823+
]
824+
},
825+
{
826+
send: 'import { export1, export2 } from "module-name"',
827+
expect: [
828+
kSource,
829+
kArrow,
830+
'',
831+
'Uncaught:',
832+
'SyntaxError: Cannot use import statement inside the Node.js REPL, \
833+
alternatively use dynamic import: const { export1, export2 } = await import("module-name");',
834+
]
835+
},
836+
{
837+
send: 'import * as name from "module-name";',
838+
expect: [
839+
kSource,
840+
kArrow,
841+
'',
842+
'Uncaught:',
843+
'SyntaxError: Cannot use import statement inside the Node.js REPL, \
844+
alternatively use dynamic import: const name = await import("module-name");',
845+
]
846+
},
847+
{
848+
send: 'import "module-name";',
849+
expect: [
850+
kSource,
851+
kArrow,
852+
'',
853+
'Uncaught:',
854+
'SyntaxError: Cannot use import statement inside the Node.js REPL, \
855+
alternatively use dynamic import: await import("module-name");',
856+
]
857+
},
858+
{
859+
send: 'import { export1 as localName1, export2 } from "bar";',
860+
expect: [
861+
kSource,
862+
kArrow,
863+
'',
864+
'Uncaught:',
865+
'SyntaxError: Cannot use import statement inside the Node.js REPL, \
866+
alternatively use dynamic import: const { export1: localName1, export2 } = await import("bar");',
867+
]
868+
},
869+
{
870+
send: 'import alias from "bar";',
871+
expect: [
872+
kSource,
873+
kArrow,
874+
'',
875+
'Uncaught:',
876+
'SyntaxError: Cannot use import statement inside the Node.js REPL, \
877+
alternatively use dynamic import: const { default: alias } = await import("bar");',
878+
]
879+
},
880+
{
881+
send: 'import alias, {namedExport} from "bar";',
882+
expect: [
883+
kSource,
884+
kArrow,
885+
'',
886+
'Uncaught:',
887+
'SyntaxError: Cannot use import statement inside the Node.js REPL, \
888+
alternatively use dynamic import: const { default: alias, namedExport } = await import("bar");',
822889
]
823890
},
824891
];

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.