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,
@@ -105,7 +107,9 @@ const {
105
107
const {
106
108
isIdentifierStart,
107
109
isIdentifierChar,
110
+ parse : acornParse ,
108
111
} = require ( 'internal/deps/acorn/acorn/dist/acorn' ) ;
112
+ const acornWalk = require ( 'internal/deps/acorn/acorn-walk/dist/walk' ) ;
109
113
const {
110
114
decorateErrorStack,
111
115
isError,
@@ -225,6 +229,28 @@ module.paths = CJSModule._nodeModulePaths(module.filename);
225
229
const writer = ( obj ) => inspect ( obj , writer . options ) ;
226
230
writer . options = { ...inspect . defaultOptions , showProxy : true } ;
227
231
232
+ // Converts static import statement to dynamic import statement
233
+ const toDynamicImport = ( codeLine ) => {
234
+ let dynamicImportStatement = '' ;
235
+ const ast = acornParse ( codeLine , { __proto__ : null , sourceType : 'module' , ecmaVersion : 'latest' } ) ;
236
+ acornWalk . ancestor ( ast , {
237
+ ImportDeclaration ( node ) {
238
+ const awaitDynamicImport = `await import(${ JSONStringify ( node . source . value ) } );` ;
239
+ if ( node . specifiers . length === 0 ) {
240
+ dynamicImportStatement += awaitDynamicImport ;
241
+ } else if ( node . specifiers . length === 1 && node . specifiers [ 0 ] . type === 'ImportNamespaceSpecifier' ) {
242
+ dynamicImportStatement += `const ${ node . specifiers [ 0 ] . local . name } = ${ awaitDynamicImport } ` ;
243
+ } else {
244
+ const importNames = ArrayPrototypeJoin ( ArrayPrototypeMap ( node . specifiers , ( { local, imported } ) =>
245
+ ( local . name === imported ?. name ? local . name : `${ imported ?. name ?? 'default' } : ${ local . name } ` ) ,
246
+ ) , ', ' ) ;
247
+ dynamicImportStatement += `const { ${ importNames } } = ${ awaitDynamicImport } ` ;
248
+ }
249
+ } ,
250
+ } ) ;
251
+ return dynamicImportStatement ;
252
+ } ;
253
+
228
254
function REPLServer ( prompt ,
229
255
stream ,
230
256
eval_ ,
@@ -686,7 +712,7 @@ function REPLServer(prompt,
686
712
'module' ;
687
713
if ( StringPrototypeIncludes ( e . message , importErrorStr ) ) {
688
714
e . message = 'Cannot use import statement inside the Node.js ' +
689
- 'REPL, alternatively use dynamic import' ;
715
+ 'REPL, alternatively use dynamic import: ' + toDynamicImport ( ArrayPrototypeAt ( self . lines , - 1 ) ) ;
690
716
e . stack = SideEffectFreeRegExpPrototypeSymbolReplace (
691
717
/ S y n t a x E r r o r : .* \n / ,
692
718
e . stack ,
0 commit comments