import { defineConfig } from "vite"; import vue from "@vitejs/plugin-vue"; import AutoImport from "unplugin-auto-import/vite"; import Components from "unplugin-vue-components/vite"; import { ElementPlusResolver } from "unplugin-vue-components/resolvers"; import fs from "node:fs"; import os from "node:os"; import path from "node:path"; // @ts-expect-error process is a nodejs global const host = process.env.TAURI_DEV_HOST; const APP_NAME = "call-client"; const CONFIG_FILE_NAME = "config.json"; const API_QUEUE_CALLER_PATH = "/api/queue/caller"; const DEFAULT_API_PORT = 8845; /** * 获取当前用户目录。 */ function getHomeDirectory(): string { return process.env.HOME || process.env.USERPROFILE || os.homedir() || "."; } /** * 获取开发环境下的配置文件路径。 */ function getConfigFilePath(): string { if (process.platform === "linux") { const xdgConfigHome = process.env.XDG_CONFIG_HOME; const baseDirectory = xdgConfigHome && path.isAbsolute(xdgConfigHome) ? xdgConfigHome : path.join(getHomeDirectory(), ".config"); return path.join(baseDirectory, APP_NAME, CONFIG_FILE_NAME); } if (process.env.APPDATA) { return path.join(process.env.APPDATA, APP_NAME, CONFIG_FILE_NAME); } return path.join(getHomeDirectory(), `.${APP_NAME}`, CONFIG_FILE_NAME); } /** * 将配置中的 server_ip 规范化为 Vite 代理 target。 */ function buildProxyTarget(serverIp: string): string { const raw = serverIp.trim(); if (!raw) { return ""; } if (raw.startsWith("http://") || raw.startsWith("https://")) { return raw.replace(/\/$/, ""); } const hostPort = raw.replace(/^\/+/, ""); const hasPort = /:\d+$/.test(hostPort) || /^\[.+\]:\d+$/.test(hostPort); if (hasPort) { return `http://${hostPort}`; } return `http://${hostPort}:${DEFAULT_API_PORT}`; } /** * 从本地 config.json 读取开发代理目标地址。 */ function resolveProxyTarget(): string { const configFilePath = getConfigFilePath(); if (!fs.existsSync(configFilePath)) { return ""; } try { const content = fs.readFileSync(configFilePath, "utf8"); const parsed = JSON.parse(content) as Record; const serverIp = typeof parsed.server_ip === "string" ? parsed.server_ip : ""; return buildProxyTarget(serverIp); } catch { return ""; } } const proxyTarget = resolveProxyTarget(); // https://vite.dev/config/ export default defineConfig(async () => ({ plugins: [ vue(), AutoImport({ imports: ["vue", "vue-router"], dts: false, resolvers: [ElementPlusResolver()], }), Components({ dts: false, resolvers: [ElementPlusResolver()], }), ], build: { rollupOptions: { output: { manualChunks(id) { if (!id.includes("node_modules")) { return undefined; } if (id.includes("element-plus") || id.includes("@element-plus")) { return "vendor-element-plus"; } if (id.includes("vue-router")) { return "vendor-router"; } if (id.includes("axios")) { return "vendor-axios"; } if (id.includes("node_modules/vue/") || id.includes("node_modules/@vue/")) { return "vendor-vue"; } return "vendor-misc"; }, }, }, }, // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build` // // 1. prevent Vite from obscuring rust errors clearScreen: false, // 2. tauri expects a fixed port, fail if that port is not available server: { port: 1420, strictPort: true, host: host || false, proxy: proxyTarget ? { [API_QUEUE_CALLER_PATH]: { target: proxyTarget, changeOrigin: true, }, } : undefined, hmr: host ? { protocol: "ws", host, port: 1421, } : undefined, watch: { // 3. tell Vite to ignore watching `src-tauri` ignored: ["**/src-tauri/**"], }, }, }));