import { defineConfig, type Plugin } from 'vite' import vue from '@vitejs/plugin-vue' // Service Worker als Build-Artefakt: Die Cache-Version ist der Build-Zeitstempel, // damit Browser nach jedem Deploy den SW aktualisieren und alte Caches räumen. const SW_SOURCE = ` const VERSION = 'wp-__SW_VERSION__'; const CACHE_NAME = 'wannpassts-' + VERSION; const PRECACHE = [ '/', '/manifest.webmanifest', '/favicon.svg', '/icons/icon-192.png', '/icons/icon-512.png', '/icons/icon-maskable-512.png', '/icons/apple-touch-icon.png', ]; self.addEventListener('install', (event) => { event.waitUntil((async () => { const cache = await caches.open(CACHE_NAME); await cache.addAll(PRECACHE).catch(() => {}); await self.skipWaiting(); })()); }); self.addEventListener('activate', (event) => { event.waitUntil((async () => { const keys = await caches.keys(); await Promise.all(keys.filter((k) => k !== CACHE_NAME).map((k) => caches.delete(k))); await self.clients.claim(); })()); }); self.addEventListener('fetch', (event) => { const req = event.request; if (req.method !== 'GET') return; const url = new URL(req.url); if (url.origin !== self.location.origin) return; // API-Aufrufe immer live – niemals aus dem Cache bedienen. if (url.pathname.startsWith('/api/')) return; // Navigation: Netzwerk zuerst, offline App-Shell aus dem Cache. if (req.mode === 'navigate') { event.respondWith((async () => { try { const res = await fetch(req); const cache = await caches.open(CACHE_NAME); cache.put('/', res.clone()); return res; } catch (err) { const cached = (await caches.match(req)) || (await caches.match('/')); if (cached) return cached; return new Response('Offline – bitte Internetverbindung prüfen.', { status: 503, headers: { 'Content-Type': 'text/plain; charset=utf-8' }, }); } })()); return; } // Statische Assets: Cache zuerst (gehashte Namen sind unveränderlich). event.respondWith((async () => { const cached = await caches.match(req, { ignoreSearch: true }); if (cached) return cached; const res = await fetch(req); if (res.ok) { const cache = await caches.open(CACHE_NAME); cache.put(req, res.clone()); } return res; })()); }); ` function serviceWorkerPlugin(): Plugin { return { name: 'wannpassts-sw', apply: 'build', generateBundle() { this.emitFile({ type: 'asset', fileName: 'sw.js', source: SW_SOURCE.replace('__SW_VERSION__', new Date().toISOString()), }) }, } } export default defineConfig({ plugins: [vue(), serviceWorkerPlugin()], server: { port: 5173, proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true }, }, }, })