import react from "@vitejs/plugin-react"; import { VitePWA } from "vite-plugin-pwa"; import tailwindcss from "@tailwindcss/vite"; import { defineConfig } from "vite"; export default defineConfig({ plugins: [ react(), tailwindcss(), VitePWA({ registerType: "autoUpdate", includeAssets: ["icon.svg"], manifest: { name: "BookLib 个人书库", short_name: "BookLib", description: "个人书库/漫画库在线阅读", theme_color: "#09090b", background_color: "#09090b", display: "standalone", icons: [{ src: "icon.svg", sizes: "any", type: "image/svg+xml", purpose: "any" }], }, workbox: { globPatterns: ["**/*.{js,css,html,svg,woff2}"], navigateFallback: "/index.html", runtimeCaching: [ { // ?v={hash} 的封面/CBZ 页/原文件 = 不可变 → cache-first(spec §6.1/§6.3) urlPattern: ({ url }) => url.pathname.startsWith("/api/books/") && url.search.includes("v=") && (/\/cover$/.test(url.pathname) || /\/pages\/\d+$/.test(url.pathname) || /\/file$/.test(url.pathname)), handler: "CacheFirst", options: { cacheName: "booklib-immutable", expiration: { maxEntries: 3000, purgeOnQuotaError: true } }, }, { // 普通 API 请求 network-first,离线可读最近一次列表/进度 urlPattern: ({ url }) => url.pathname.startsWith("/api/"), handler: "NetworkFirst", options: { cacheName: "booklib-api", networkTimeoutSeconds: 5, expiration: { maxAgeSeconds: 3600, maxEntries: 200 }, }, }, ], }, }), ], server: { proxy: { "/api": "http://localhost:8080" } }, });