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 { NaiveUiResolver } from 'unplugin-vue-components/resolvers' import { VitePWA } from 'vite-plugin-pwa' import { fileURLToPath, URL } from 'node:url' // 注:这份是真实生效的 Vite 配置(以 .js 输出,Vite 优先读 .js 而不是 .ts)。 // vite.config.ts 留作类型参考;两文件内容保持一致。 export default defineConfig({ plugins: [ vue(), AutoImport({ imports: [ 'vue', 'vue-router', { 'naive-ui': [ 'useDialog', 'useMessage', 'useNotification', 'useLoadingBar', ], }, ], dts: 'src/auto-imports.d.ts', }), Components({ resolvers: [NaiveUiResolver()], dts: 'src/components.d.ts', }), VitePWA({ // 自动注册,生成 SW,预缓存全部构建产物 registerType: 'autoUpdate', injectRegister: 'auto', // 静态 manifest:用 public/manifest.webmanifest 写好,这里关掉自动生成, // 避免 Node 在 Windows 中文环境下把 manifest 写成 GBK 乱码 manifest: false, // 走 pwaAssetDirectory / filename 显式输出 filename: 'sw.js', strategies: 'generateSW', injectManifest: { globPatterns: ['**/*.{js,css,html,ico,png,svg,woff2}'] }, includeAssets: [ 'favicon.svg', 'pwa-192x192.png', 'pwa-512x512.png', 'pwa-maskable-512x512.png', 'manifest.webmanifest', ], workbox: { globPatterns: ['**/*.{js,css,html,ico,png,svg,woff2}'], cleanupOutdatedCaches: true, navigateFallback: '/index.html', navigateFallbackDenylist: [/^\/api/], runtimeCaching: [ { // API GET 走 network-first,失败回退 cache urlPattern: ({ url }) => url.pathname.startsWith('/api/'), handler: 'NetworkFirst', options: { cacheName: 'api-cache', networkTimeoutSeconds: 5, expiration: { maxEntries: 50, maxAgeSeconds: 60 * 60 * 24 }, cacheableResponse: { statuses: [0, 200] }, }, }, { // 静态资源 cache-first urlPattern: ({ request }) => ['style', 'script', 'worker', 'image', 'font'].includes(request.destination), handler: 'CacheFirst', options: { cacheName: 'asset-cache', expiration: { maxEntries: 200, maxAgeSeconds: 60 * 60 * 24 * 30 }, }, }, ], }, devOptions: { // 开发期关掉 SW(经常把 Vite HMR 卡住);真要验证再开 enabled: false, }, }), ], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)), }, }, server: { host: '127.0.0.1', port: 5173, proxy: { '/api': { target: 'http://127.0.0.1:8080', changeOrigin: true, }, }, }, build: { target: 'es2020', sourcemap: false, }, })