vite.config.ts
Rama main · réplica de lectura del repositorio original.
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import path from "node:path";
const host = process.env.TAURI_DEV_HOST;
// Vendor libraries that get their own long-lived chunk. Everything here is
// either heavy and only reached from a lazily-loaded surface (CodeMirror,
// xterm, mermaid, the markdown/highlight stack) or shared by the whole app
// and rarely changing (react, lucide, tauri) — splitting it keeps the startup
// bundle down to app code and lets the webview cache the vendor chunks across
// releases that only touch app code. Matching is on the package directory
// under node_modules, so scoped packages match on their scope.
const VENDOR_CHUNKS: Array<[chunk: string, packages: string[]]> = [
[
"vendor-codemirror",
[
"@codemirror",
"codemirror",
"@lezer",
"style-mod",
"w3c-keyname",
"crelt",
],
],
["vendor-xterm", ["@xterm"]],
["vendor-mermaid", ["mermaid"]],
["vendor-highlight", ["highlight.js", "lowlight", "rehype-highlight"]],
[
"vendor-markdown",
[
"react-markdown",
"remark-gfm",
"remark-parse",
"remark-rehype",
"rehype-",
"remark-",
"mdast-",
"micromark",
"hast-",
"unist-",
"unified",
"vfile",
"bail",
"trough",
"devlop",
"zwitch",
"ccount",
"longest-streak",
"markdown-table",
"trim-lines",
"property-information",
"space-separated-tokens",
"comma-separated-tokens",
"html-url-attributes",
"estree-util-is-identifier-name",
"decode-named-character-reference",
"character-entities",
"style-to-js",
"style-to-object",
"inline-style-parser",
],
],
["vendor-lucide", ["lucide-react"]],
["vendor-react", ["react", "react-dom", "scheduler"]],
["vendor-tauri", ["@tauri-apps"]],
];
/** Package directory name (`@scope/name` → `@scope`, `name@1.2.3` in pnpm
* stores → `name`) for a module id under node_modules, or null. */
function vendorPackage(id: string): string | null {
const marker = "node_modules/";
const at = id.lastIndexOf(marker);
if (at < 0) return null;
const rest = id.slice(at + marker.length);
const first = rest.split("/")[0];
// pnpm virtual-store entries look like `.pnpm/react@18.3.1/node_modules/react`
// — `lastIndexOf` above already landed us on the real package dir, so
// `first` is the bare name (or scope) here.
return first.startsWith(".") ? null : first;
}
function manualChunks(id: string): string | undefined {
const pkg = vendorPackage(id);
if (!pkg) return undefined;
for (const [chunk, packages] of VENDOR_CHUNKS) {
for (const p of packages) {
if (p.endsWith("-") ? pkg.startsWith(p) : pkg === p) return chunk;
}
}
return undefined;
}
export default defineConfig(async () => ({
plugins: [react()],
resolve: {
alias: { "@": path.resolve(__dirname, "./src") },
},
clearScreen: false,
build: {
// WebView2 (Chromium, evergreen) and WebKitGTK ≥ 2.40 both implement
// ES2022 natively, so ship modern syntax instead of down-levelling class
// fields / optional chaining / top-level await into slower shims.
target: "es2022",
rollupOptions: {
output: { manualChunks },
},
// The mermaid chunk alone is well over the default 500 kB advisory; it is
// only fetched when the Architecture tab renders a diagram.
chunkSizeWarningLimit: 1_500,
},
server: {
port: 1420,
strictPort: true,
host: host || false,
hmr: host ? { protocol: "ws", host, port: 1421 } : undefined,
watch: { ignored: ["**/src-tauri/**"] },
},
}));