From d6a9a269a7f24f943002caa72770eb2ad2fc3dab Mon Sep 17 00:00:00 2001 From: Seth Trowbridge Date: Sat, 1 Jul 2023 10:43:29 -0400 Subject: [PATCH] apply import maps --- example/dyn-test.tsx | 5 +++- run-serve.tsx | 65 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 59 insertions(+), 11 deletions(-) diff --git a/example/dyn-test.tsx b/example/dyn-test.tsx index 6bb8bf1..63ca671 100644 --- a/example/dyn-test.tsx +++ b/example/dyn-test.tsx @@ -1,6 +1,9 @@ +import * as Util from "@able/"; +import * as React from "react"; +import {createElement} from "react/client"; -import('https://esm.sh/react').then((module) => { +import('react').then((module) => { console.log(module); }); diff --git a/run-serve.tsx b/run-serve.tsx index b0dc224..bb93c77 100644 --- a/run-serve.tsx +++ b/run-serve.tsx @@ -57,12 +57,17 @@ let Configuration:Configuration = Spoof: "/@able", async Serve(inReq, inURL, inExt, inMap, inConfig) { - if(inReq.headers.get("user-agent")?.startsWith("Deno")) + if( inReq.headers.get("user-agent")?.startsWith("Deno") || inURL.searchParams.get("deno") ) { + console.log("patching...") const file = await fetch(inConfig.Proxy + inURL.pathname); const text = await file.text(); - return new Response(Transpile.Patch(text), {headers:{"content-type":"application/javascript"}} ); + return new Response(Transpile.Patch(text, inMap), {headers:{"content-type":"application/javascript"}} ); + } + else + { + console.log("not a deno-able file") } }, Remap: (inImports, inConfig)=> @@ -139,20 +144,60 @@ export const Transpile = ImportMapReload(); return size; }, - Patch(inText) + /** + * Converts dynamic module imports in to static, also can resolve paths with an import map + */ + Patch(inText:string, inMap?:DenoConfig) { - const regex = /(? + { + const match = inMap.imports[inPath]; + if(match) + { + return match; + } + else if(inPath.includes("/")) + { + let bestKey = ""; + let bestLength = 0; + Object.keys(inMap.imports).forEach((key, i, arr)=> + { + if(key.endsWith("/") && inPath.startsWith(key) && key.length > bestLength) + { + bestKey = key; + bestLength = bestLength; + } + }); + if(bestKey) + { + return inMap.imports[bestKey]+inPath.substring(bestKey.length); + } + } + return inPath; + } + : (inPath:string)=>inPath; + let match, regex; let convertedBody = inText; + + // remap static imports + regex = /from\s+(['"`])(.*?)\1/g; + while ((match = regex.exec(inText))) + { + const importStatement = match[0]; + const importPath = match[2]; + convertedBody = convertedBody.replace(importStatement, `from "${remap(importPath)}"`); + } + + // convert dynamic imports into static (to work around deno deploy) + const staticImports = []; + regex = /(?