Skip to content

Commit

Permalink
External entry points (#30)
Browse files Browse the repository at this point in the history
### What does this change?
Simplify the build output by marking islands as external, reducing the
number of chunks produced by the bundle splitting.

#### Before

```js
// file: RedThenBlue.island.js
import {
  GreenThenPink_island_default
} from "./chunk-WLNA4ATP.js";

// file: GreenThenPink.island.js
import {
  GreenThenPink_island_default
} from "./chunk-WLNA4ATP.js";
import "./chunk-JA2UCGWR.js";
export {
  GreenThenPink_island_default as default
};

```

#### After

```js
// file: RedThenBlue.island.js
import GreenThenPink from "./GreenThenPink.island.js";

// file: GreenThenPink.island.js
var GreenThenPink_island = class extends SvelteComponent {
  constructor(options) {
    super();
    init(this, options, instance, create_fragment, safe_not_equal, {}, add_css);
  }
};
var GreenThenPink_island_default = GreenThenPink_island;
export {
  GreenThenPink_island_default as default
};
```
  • Loading branch information
mxdvl authored Apr 24, 2023
2 parents 6bcc110 + c96c747 commit aad2eb5
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 14 deletions.
15 changes: 5 additions & 10 deletions src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,10 @@ const baseESBuildConfig = {
} as const satisfies Partial<esbuild.BuildOptions>;

const routesESBuildConfig: esbuild.BuildOptions = {
entryPoints: [
await get_svelte_files({ dir: "routes/" }),
]
.flat(),
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 }),
],
Expand All @@ -75,12 +72,10 @@ const routesESBuildConfig: esbuild.BuildOptions = {
};

const islandsESBuildConfig: esbuild.BuildOptions = {
entryPoints: [
await get_svelte_files({ dir: "components/" }),
]
.flat(),
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/",
Expand Down
25 changes: 21 additions & 4 deletions src/esbuild_plugins/islands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
});
Expand Down

0 comments on commit aad2eb5

Please sign in to comment.