cents/apps/web/vite.config.ts

97 lines
2.9 KiB
TypeScript

import vue from "@vitejs/plugin-vue";
import { defineConfig, loadEnv, type Plugin } from "vite";
const monorepoRoot = new URL("../..", import.meta.url).pathname;
type AppVariant = "dev" | "pro";
function appIdentityPlugin(mode: string): Plugin {
const env = loadEnv(mode, monorepoRoot, "");
const envValue = (name: string) => process.env[name] || env[name];
const defaultVariant: AppVariant = mode === "development" ? "dev" : "pro";
const configuredVariant = envValue("APP_VARIANT");
const variant: AppVariant = configuredVariant === "dev" || configuredVariant === "pro" ? configuredVariant : defaultVariant;
const appName = envValue("VITE_APP_NAME") || (variant === "dev" ? "有数记账 Dev" : "有数记账");
const shortName = envValue("VITE_APP_SHORT_NAME") || appName;
const appId = envValue("VITE_APP_ID") || (variant === "dev" ? "/?app=cents-dev" : "/?app=cents");
const iconPrefix = variant === "dev" ? "icon-dev" : "icon";
const appleTouchIcon = variant === "dev" ? "/apple-touch-icon-dev.png" : "/apple-touch-icon.png";
const manifest = JSON.stringify(
{
name: appName,
short_name: shortName,
id: appId,
description: "家庭共享账本",
start_url: "/",
display: "standalone",
background_color: "#ffffff",
theme_color: "#43c9bd",
icons: [
{
src: `/${iconPrefix}-192.png`,
sizes: "192x192",
type: "image/png",
purpose: "any",
},
{
src: `/${iconPrefix}-512.png`,
sizes: "512x512",
type: "image/png",
purpose: "any",
},
{
src: `/${iconPrefix}-maskable-512.png`,
sizes: "512x512",
type: "image/png",
purpose: "maskable",
},
],
},
null,
2,
);
return {
name: "cents-app-identity",
configureServer(server) {
server.middlewares.use((req, res, next) => {
if (req.url?.split("?")[0] !== "/manifest.webmanifest") {
next();
return;
}
res.setHeader("Content-Type", "application/manifest+json; charset=utf-8");
res.end(manifest);
});
},
transformIndexHtml(html) {
return html
.replace(/<title>.*<\/title>/, `<title>${appName}</title>`)
.replace('href="/icon-192.png"', `href="/${iconPrefix}-192.png"`)
.replace('href="/apple-touch-icon.png"', `href="${appleTouchIcon}"`);
},
generateBundle() {
this.emitFile({
type: "asset",
fileName: "manifest.webmanifest",
source: manifest,
});
},
};
}
export default defineConfig(({ mode }) => ({
envDir: monorepoRoot,
plugins: [vue(), appIdentityPlugin(mode)],
server: {
allowedHosts: ["dev.cents.homemade.net.cn"],
proxy: {
"/api": {
target: "http://127.0.0.1:3000",
changeOrigin: false,
},
},
},
}));