43
43
'use strict' ;
44
44
45
45
const {
46
+ ArrayPrototypeAt,
46
47
ArrayPrototypeFilter,
47
48
ArrayPrototypeFindIndex,
48
49
ArrayPrototypeForEach,
@@ -62,6 +63,7 @@ const {
62
63
Boolean,
63
64
Error,
64
65
FunctionPrototypeBind,
66
+ JSONStringify,
65
67
MathMaxApply,
66
68
NumberIsNaN,
67
69
NumberParseFloat,
@@ -104,7 +106,9 @@ const {
104
106
const {
105
107
isIdentifierStart,
106
108
isIdentifierChar,
109
+ parse : acornParse ,
107
110
} = require ( 'internal/deps/acorn/acorn/dist/acorn' ) ;
111
+ const acornWalk = require ( 'internal/deps/acorn/acorn-walk/dist/walk' ) ;
108
112
const {
109
113
decorateErrorStack,
110
114
isError,
@@ -223,6 +227,28 @@ module.paths = CJSModule._nodeModulePaths(module.filename);
223
227
const writer = ( obj ) => inspect ( obj , writer . options ) ;
224
228
writer . options = { ...inspect . defaultOptions , showProxy : true } ;
225
229
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
+
226
252
function REPLServer ( prompt ,
227
253
stream ,
228
254
eval_ ,
@@ -684,7 +710,7 @@ function REPLServer(prompt,
684
710
'module' ;
685
711
if ( StringPrototypeIncludes ( e . message , importErrorStr ) ) {
686
712
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 ) ) ;
688
714
e . stack = SideEffectFreeRegExpPrototypeSymbolReplace (
689
715
/ S y n t a x E r r o r : .* \n / ,
690
716
e . stack ,
0 commit comments