122 lines
3.4 KiB
JavaScript
122 lines
3.4 KiB
JavaScript
import path from "node:path";
|
|
import process from "node:process";
|
|
import { fileURLToPath } from "node:url";
|
|
import builtins from "builtin-modules";
|
|
import esbuild from "esbuild";
|
|
import sveltePlugin from "esbuild-svelte";
|
|
|
|
export const root = path.dirname(fileURLToPath(import.meta.url));
|
|
export const LIB = path.resolve(root, "../beaver-gateway/ui/src/lib");
|
|
|
|
const EXTERNAL = [
|
|
"obsidian",
|
|
"electron",
|
|
"@codemirror/autocomplete",
|
|
"@codemirror/collab",
|
|
"@codemirror/commands",
|
|
"@codemirror/language",
|
|
"@codemirror/lint",
|
|
"@codemirror/search",
|
|
"@codemirror/state",
|
|
"@codemirror/view",
|
|
"@lezer/common",
|
|
"@lezer/highlight",
|
|
"@lezer/lr",
|
|
...builtins,
|
|
];
|
|
|
|
const LIB_IMPORT = /^\$lib\//;
|
|
const APP_IMPORT = /^\$app\//;
|
|
const SONNER_IMPORT = /^svelte-sonner$/;
|
|
const OBSIDIAN_IMPORT = /^obsidian$/;
|
|
const BARE_IMPORT = /^[^./#]/;
|
|
|
|
function isExternal(specifier) {
|
|
return (
|
|
specifier.startsWith("node:") ||
|
|
EXTERNAL.some(
|
|
(name) => specifier === name || specifier.startsWith(`${name}/`)
|
|
)
|
|
);
|
|
}
|
|
|
|
// The panel is beaver-gateway's ``ui/src/lib``, compiled into this plugin.
|
|
// Two rules keep it one bundle: ``$lib/*`` points at that directory, and
|
|
// every bare import - svelte, bits-ui, the icons - resolves from this
|
|
// plugin's node_modules, never from the gateway's, so there is exactly one
|
|
// Svelte runtime. ``svelte-sonner`` becomes Obsidian notices; ``$app/*``
|
|
// is SvelteKit-only and refused.
|
|
export function sharedLib({ obsidian = "external" } = {}) {
|
|
return {
|
|
name: "beaver-shared-lib",
|
|
setup(build) {
|
|
build.onResolve({ filter: LIB_IMPORT }, (args) =>
|
|
build.resolve(`./${args.path.slice("$lib/".length)}`, {
|
|
kind: args.kind,
|
|
pluginData: { pinned: true },
|
|
resolveDir: LIB,
|
|
})
|
|
);
|
|
build.onResolve({ filter: APP_IMPORT }, (args) => ({
|
|
errors: [
|
|
{
|
|
text: `${args.path} is SvelteKit-only; the panel must not import it`,
|
|
},
|
|
],
|
|
}));
|
|
build.onResolve({ filter: SONNER_IMPORT }, () => ({
|
|
path: path.join(root, "src/shims/sonner.ts"),
|
|
}));
|
|
build.onResolve({ filter: OBSIDIAN_IMPORT }, () =>
|
|
obsidian === "external"
|
|
? { external: true, path: "obsidian" }
|
|
: { path: obsidian }
|
|
);
|
|
build.onResolve({ filter: BARE_IMPORT }, (args) => {
|
|
if (args.pluginData?.pinned) {
|
|
return;
|
|
}
|
|
if (isExternal(args.path)) {
|
|
return { external: true, path: args.path };
|
|
}
|
|
return build.resolve(args.path, {
|
|
kind: args.kind,
|
|
pluginData: { pinned: true },
|
|
resolveDir: root,
|
|
});
|
|
});
|
|
},
|
|
};
|
|
}
|
|
|
|
export const svelte = () =>
|
|
sveltePlugin({
|
|
compilerOptions: { css: "injected", runes: true },
|
|
filterWarnings: (warning) => !warning.filename?.includes("node_modules"),
|
|
});
|
|
|
|
const prod = process.argv[2] === "production";
|
|
|
|
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
const ctx = await esbuild.context({
|
|
bundle: true,
|
|
conditions: ["svelte", "browser"],
|
|
entryPoints: ["src/main.ts"],
|
|
format: "cjs",
|
|
logLevel: "info",
|
|
mainFields: ["svelte", "browser", "module", "main"],
|
|
minify: prod,
|
|
outfile: "main.js",
|
|
plugins: [sharedLib(), svelte()],
|
|
sourcemap: prod ? false : "inline",
|
|
target: "es2022",
|
|
treeShaking: true,
|
|
});
|
|
if (prod) {
|
|
await ctx.rebuild();
|
|
await ctx.dispose();
|
|
} else {
|
|
await ctx.watch();
|
|
}
|
|
}
|