Skip to content

Instantly share code, notes, and snippets.

@bigmistqke
Last active November 5, 2023 03:17
Show Gist options
  • Save bigmistqke/eccc76b12c755041e6eadb08a9e85ab8 to your computer and use it in GitHub Desktop.
Save bigmistqke/eccc76b12c755041e6eadb08a9e85ab8 to your computer and use it in GitHub Desktop.
dynamic esm modules with tag template literal
import {
onCleanup,
createMemo,
createSignal,
type Accessor,
createEffect,
createResource,
} from "solid-js";
function modifyImportPaths(code) {
return code.replace(/import (\w+) from ["']([^"']+)["']/g, (match, varName, path) => {
if (path.startsWith("blob:") || path.startsWith("http:") || path.startsWith("https:") || path.startsWith(".")) {
return `import ${varName} from "${path}"`;
} else {
return `import ${varName} from "https://cdn.skypack.dev/${path}"`;
}
});
}
function javascript(
strings: TemplateStringsArray,
...holes: Accessor<any>[]
): Accessor<string> {
const memo = createMemo(() => {
const content = strings.reduce((acc, str, idx) => {
return acc + str + (holes[idx]?.() || "");
}, "");
const blobUrl = URL.createObjectURL(
new Blob([modifyImportPaths(content)], { type: "application/javascript" }),
);
onCleanup(() => URL.revokeObjectURL(blobUrl));
return blobUrl;
});
return memo;
}
const load = (url: Accessor<string>) =>
createResource(url, (url) => import(url))[0];
const [signal, setSignal] = createSignal("hallo");
const y = javascript`
import confetti from 'canvas-confetti';
confetti()
export default "${signal}";
`;
const x = javascript`
import y from "${y}";
import randomcolor from 'randomcolor';
export default y + " " + randomcolor();
`;
const resolved = load(x);
createEffect(() => {
if (resolved()) {
console.log("result", resolved()?.default);
setTimeout(() => setSignal("goodbye"), 1000);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment