Files
gerbeur/vite.config.ts

82 lines
2.2 KiB
TypeScript

import { defineConfig, type Plugin } from "vite";
import react from "@vitejs/plugin-react-swc";
import { lingui } from "@lingui/vite-plugin";
import fs from "node:fs";
import path from "node:path";
function manifestPlugin(): Plugin {
const cssPath = path.resolve("src/index.css");
const outPath = path.resolve("public/manifest.webmanifest");
function cssVar(rootBlock: string, name: string): string | undefined {
return rootBlock.match(
new RegExp(`${name.replace("-", "\\-")}:\\s*(#[0-9a-fA-F]{3,8})`),
)?.[1];
}
function generate() {
const css = fs.readFileSync(cssPath, "utf-8");
// Only read the first :root block — dark-mode defaults, before any @media overrides
const rootBlock = css.match(/:root\s*\{([^}]+)\}/)?.[1] ?? "";
const bgColor = cssVar(rootBlock, "--color-bg") ?? "#111827";
const manifest = {
name: "gerbeur",
short_name: "gerbeur",
start_url: "/",
display: "standalone",
background_color: bgColor,
theme_color: bgColor,
icons: [{ src: "/favicon.svg", type: "image/svg+xml", sizes: "any" }],
share_target: {
action: "/",
method: "GET",
params: { url: "share_url", title: "share_title", text: "share_text" },
},
};
fs.writeFileSync(outPath, JSON.stringify(manifest, null, 2) + "\n");
}
return {
name: "generate-manifest",
buildStart: generate,
configureServer(server) {
generate();
server.watcher.on("change", (file) => {
if (path.resolve(file) === cssPath) generate();
});
},
};
}
export default defineConfig({
server: {
port: 3000,
watch: {
ignored: ["**/api/**"],
},
},
build: {
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes("react-markdown") || id.includes("remark-gfm") || id.includes("remark-parse") || id.includes("mdast") || id.includes("micromark") || id.includes("unist")) {
return "vendor-markdown";
}
if (id.includes("node_modules")) {
return "vendor";
}
},
},
},
},
plugins: [
manifestPlugin(),
lingui(),
react({
plugins: [["@lingui/swc-plugin", {}]],
}),
],
});