GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — repl: display dynamic import variant in static import error messages · nodejs/node@bbafd42

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
  • lib
    • repl.js
  • test/parallel
    • test-repl.js
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎lib/repl.js‎

Copy file name to clipboardExpand all lines: lib/repl.js
+26-1Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ const {
6262
Boolean,
6363
Error,
6464
FunctionPrototypeBind,
65+
JSONStringify,
6566
MathMaxApply,
6667
NumberIsNaN,
6768
NumberParseFloat,
@@ -105,7 +106,9 @@ const {
105106
const {
106107
isIdentifierStart,
107108
isIdentifierChar,
109+
parse: acornParse,
108110
} = require('internal/deps/acorn/acorn/dist/acorn');
111+
const acornWalk = require('internal/deps/acorn/acorn-walk/dist/walk');
109112
const {
110113
decorateErrorStack,
111114
isError,
@@ -225,6 +228,28 @@ module.paths = CJSModule._nodeModulePaths(module.filename);
225228
const writer = (obj) => inspect(obj, writer.options);
226229
writer.options = { ...inspect.defaultOptions, showProxy: true };
227230

231+
// Converts static import statement to dynamic import statement
232+
const toDynamicImport = (codeLine) => {
233+
let dynamicImportStatement = '';
234+
const ast = acornParse(codeLine, { __proto__: null, sourceType: 'module', ecmaVersion: 'latest' });
235+
acornWalk.ancestor(ast, {
236+
ImportDeclaration(node) {
237+
const awaitDynamicImport = `await import(${JSONStringify(node.source.value)});`;
238+
if (node.specifiers.length === 0) {
239+
dynamicImportStatement += awaitDynamicImport;
240+
} else if (node.specifiers.length === 1 && node.specifiers[0].type === 'ImportNamespaceSpecifier') {
241+
dynamicImportStatement += `const ${node.specifiers[0].local.name} = ${awaitDynamicImport}`;
242+
} else {
243+
const importNames = ArrayPrototypeJoin(ArrayPrototypeMap(node.specifiers, ({ local, imported }) =>
244+
(local.name === imported?.name ? local.name : `${imported?.name ?? 'default'}: ${local.name}`),
245+
), ', ');
246+
dynamicImportStatement += `const { ${importNames} } = ${awaitDynamicImport}`;
247+
}
248+
},
249+
});
250+
return dynamicImportStatement;
251+
};
252+
228253
function REPLServer(prompt,
229254
stream,
230255
eval_,
@@ -686,7 +711,7 @@ function REPLServer(prompt,
686711
'module';
687712
if (StringPrototypeIncludes(e.message, importErrorStr)) {
688713
e.message = 'Cannot use import statement inside the Node.js ' +
689-
'REPL, alternatively use dynamic import';
714+
'REPL, alternatively use dynamic import: ' + toDynamicImport(self.lines.at(-1));
690715
e.stack = SideEffectFreeRegExpPrototypeSymbolReplace(
691716
/SyntaxError:.*\n/,
692717
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
@@ -817,7 +817,74 @@ const tcpTests = [
817817
kArrow,
818818
'',
819819
'Uncaught:',
820-
/^SyntaxError: .* dynamic import/,
820+
'SyntaxError: Cannot use import statement inside the Node.js REPL, \
821+
alternatively use dynamic import: const { default: comeOn } = await import("fhqwhgads");',
822+
]
823+
},
824+
{
825+
send: 'import { export1, export2 } from "module-name"',
826+
expect: [
827+
kSource,
828+
kArrow,
829+
'',
830+
'Uncaught:',
831+
'SyntaxError: Cannot use import statement inside the Node.js REPL, \
832+
alternatively use dynamic import: const { export1, export2 } = await import("module-name");',
833+
]
834+
},
835+
{
836+
send: 'import * as name from "module-name";',
837+
expect: [
838+
kSource,
839+
kArrow,
840+
'',
841+
'Uncaught:',
842+
'SyntaxError: Cannot use import statement inside the Node.js REPL, \
843+
alternatively use dynamic import: const name = await import("module-name");',
844+
]
845+
},
846+
{
847+
send: 'import "module-name";',
848+
expect: [
849+
kSource,
850+
kArrow,
851+
'',
852+
'Uncaught:',
853+
'SyntaxError: Cannot use import statement inside the Node.js REPL, \
854+
alternatively use dynamic import: await import("module-name");',
855+
]
856+
},
857+
{
858+
send: 'import { export1 as localName1, export2 } from "bar";',
859+
expect: [
860+
kSource,
861+
kArrow,
862+
'',
863+
'Uncaught:',
864+
'SyntaxError: Cannot use import statement inside the Node.js REPL, \
865+
alternatively use dynamic import: const { export1: localName1, export2 } = await import("bar");',
866+
]
867+
},
868+
{
869+
send: 'import alias from "bar";',
870+
expect: [
871+
kSource,
872+
kArrow,
873+
'',
874+
'Uncaught:',
875+
'SyntaxError: Cannot use import statement inside the Node.js REPL, \
876+
alternatively use dynamic import: const { default: alias } = await import("bar");',
877+
]
878+
},
879+
{
880+
send: 'import alias, {namedExport} from "bar";',
881+
expect: [
882+
kSource,
883+
kArrow,
884+
'',
885+
'Uncaught:',
886+
'SyntaxError: Cannot use import statement inside the Node.js REPL, \
887+
alternatively use dynamic import: const { default: alias, namedExport } = await import("bar");',
821888
]
822889
},
823890
];

0 commit comments

Comments
0 (0)
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.