From 130fb9c21763a1464f14196fe60288b869dd541e Mon Sep 17 00:00:00 2001 From: DEBRIS APRON Date: Wed, 3 Aug 2022 17:01:35 -0700 Subject: [PATCH] Amend shapeshifter to allow use of dynamic import --- packages/eval/shapeshifter.mjs | 16 ++++++++++++++-- packages/eval/test/shapeshifter.test.mjs | 6 ++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/eval/shapeshifter.mjs b/packages/eval/shapeshifter.mjs index 46d7a635..500eb0ea 100644 --- a/packages/eval/shapeshifter.mjs +++ b/packages/eval/shapeshifter.mjs @@ -34,7 +34,7 @@ export const wrappedAsync = true; export default (_code) => { const { code, addReturn } = wrapAsync(_code); - const ast = parseScriptWithLocation(code); + const ast = parseScriptWithLocation(disguiseImports(code)); const artificialNodes = []; const parents = []; const shifted = replace(ast.tree, { @@ -128,10 +128,22 @@ export default (_code) => { if (wrappedAsync) { addReturn(shifted); } - const generated = codegen(shifted); + const generated = undisguiseImports(codegen(shifted)); return generated; }; +// renames all import statements to "_mport" as Shift doesn't support dynamic import. +// there shouldn't be any side-effects from this as this change does not affect +// the syntax & will be undone by the equivalent replace in "undisguiseImports". +function disguiseImports(code) { + return code.replaceAll('import', '_mport'); // Must be the same length! +} + +// Rename the renamed import statements back to "import" +function undisguiseImports(code) { + return code.replaceAll('_mport', 'import'); +} + function wrapAsync(code) { // wrap code in async to make await work on top level => this will create 1 line offset to locations // this is why line offset is -1 in getLocationObject calls below diff --git a/packages/eval/test/shapeshifter.test.mjs b/packages/eval/test/shapeshifter.test.mjs index 1cf04825..45633e8a 100644 --- a/packages/eval/test/shapeshifter.test.mjs +++ b/packages/eval/test/shapeshifter.test.mjs @@ -11,4 +11,10 @@ describe('shapeshifter', () => { it('Should shift simple double quote string', () => { assert.equal(shapeshifter('"c3"'), '(async()=>{return mini("c3").withMiniLocation([1,0,15],[1,4,19])})()'); }); + it('Should handle dynamic imports', () => { + assert.equal( + shapeshifter('const { default: foo } = await import(\'https://bar.com/foo.js\');"c3"'), + '(async()=>{const{default:foo}=await import("https://bar.com/foo.js");return mini("c3").withMiniLocation([1,64,79],[1,68,83])})()', + ); + }); });