diff --git a/src/build.ts b/src/build.ts index d128d05..d6e6d38 100644 --- a/src/build.ts +++ b/src/build.ts @@ -63,7 +63,7 @@ const routesESBuildConfig: esbuild.BuildOptions = { entryPoints: await get_svelte_files({ dir: "routes/" }), write: false, plugins: [ - island_wrapper("ssr", site_dir), + island_wrapper(site_dir), resolve_svelte_internal, build_routes({ base_path }), ], @@ -73,8 +73,9 @@ const routesESBuildConfig: esbuild.BuildOptions = { const islandsESBuildConfig: esbuild.BuildOptions = { entryPoints: await get_svelte_files({ dir: "components/" }), + write: true, plugins: [ - island_wrapper("dom", site_dir), + island_wrapper(site_dir), resolve_svelte_internal, ], outdir: build_dir + "components/", diff --git a/src/esbuild_plugins/islands.ts b/src/esbuild_plugins/islands.ts index 8466cd6..b99c802 100644 --- a/src/esbuild_plugins/islands.ts +++ b/src/esbuild_plugins/islands.ts @@ -4,15 +4,32 @@ import { compile, preprocess } from "npm:svelte/compiler"; const filter = /\.svelte$/; const name = "mononykus/svelte-islands"; -export const island_wrapper = (mode: "ssr" | "dom", dir: string): Plugin => ({ +export const island_wrapper = (dir: string): Plugin => ({ name, setup(build) { + const generate = build.initialOptions.write ? "dom" : "ssr"; + + build.onResolve({ filter }, ({ path, kind }) => { + const is_island_entry_point = generate === "dom" && + kind === "import-statement" && + // matches our `components/**/*.island.svelte`, + // perfect proxy of checking `build.initialOptions.entryPoints` + path.endsWith(".island.svelte"); + + return is_island_entry_point + ? { + path: path.replace(/\.svelte$/, ".js"), + external: true, + } + : undefined; + }); + build.onLoad({ filter }, async ({ path }) => { const filename = path.split(dir).at(-1) ?? "Undefined.svelte"; const source = await Deno.readTextFile(path); const island = filename.match(/\/(\w+).island.svelte/); - const processed = island && mode === "ssr" + const processed = island && generate === "ssr" ? (await preprocess(source, { markup: ({ content }) => { let processed = content; @@ -38,10 +55,10 @@ export const island_wrapper = (mode: "ssr" | "dom", dir: string): Plugin => ({ : source; const { js: { code } } = compile(processed, { - generate: mode, + generate, css: "injected", cssHash: ({ hash, css }) => `◖${hash(css)}◗`, - hydratable: mode === "dom", + hydratable: generate === "dom", enableSourcemap: false, filename, });