import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; import { VitePWA } from "vite-plugin-pwa"; export default defineConfig({ plugins: [ react(), VitePWA({ disable: false, registerType: "autoUpdate", includeAssets: ["pwa-192x192.png", "pwa-512x512.png", "pwa-maskable-512x512.png"], manifest: { name: "hyb-oa 移动工作台", short_name: "hyb-oa", description: "海音达工作台移动端入口,支持离线拍照上传与移动审批。", start_url: "/", display: "standalone", background_color: "#ffffff", theme_color: "#2563eb", icons: [ { src: "pwa-192x192.png", sizes: "192x192", type: "image/png", }, { src: "pwa-512x512.png", sizes: "512x512", type: "image/png", }, { src: "pwa-maskable-512x512.png", sizes: "512x512", type: "image/png", purpose: "maskable", }, ], }, workbox: { navigateFallback: "/index.html", navigateFallbackDenylist: [/^\/api\//], globPatterns: ["**/*.{js,css,html,ico,png,svg,webmanifest}"], runtimeCaching: [ { urlPattern: ({ request, url }) => ["script", "style", "font", "image"].includes(request.destination) || url.pathname.endsWith(".webmanifest"), handler: "StaleWhileRevalidate", options: { cacheName: "app-static-runtime", cacheableResponse: { statuses: [0, 200], }, expiration: { maxEntries: 120, maxAgeSeconds: 7 * 24 * 60 * 60, }, }, }, { urlPattern: ({ request, url }) => { if (request.method !== "GET") { return false; } return ( url.pathname === "/api/me" || url.pathname.startsWith("/api/workflow/tasks") || url.pathname.startsWith("/api/workflow/approvers") || url.pathname.startsWith("/api/notifications") ); }, handler: "NetworkFirst", options: { cacheName: "app-api-runtime", networkTimeoutSeconds: 3, cacheableResponse: { statuses: [200], }, expiration: { maxEntries: 80, maxAgeSeconds: 30 * 60, }, }, }, ], }, devOptions: { enabled: false, }, }), ], server: { proxy: { "/api": { target: "http://127.0.0.1:3000", changeOrigin: true, }, }, }, });