From cfa6dc4400625ede38d46f99a421d1435e743306 Mon Sep 17 00:00:00 2001 From: Gigi Date: Fri, 31 Oct 2025 01:10:20 +0100 Subject: [PATCH] feat: add development Service Worker for testing image caching With injectManifest strategy, the Service Worker needs to be built, so it's not available in dev mode. To enable testing image caching in dev, we now: 1. Created public/sw-dev.js - a simplified SW that only handles image caching 2. Updated registration to use sw-dev.js in dev mode, sw.js in production 3. Dev SW uses simple cache-first strategy for images This allows testing image caching in development without needing a build. --- public/sw-dev.js | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ src/main.tsx | 22 ++++++++++----------- vite.config.ts | 5 ++++- 3 files changed, 66 insertions(+), 12 deletions(-) create mode 100644 public/sw-dev.js diff --git a/public/sw-dev.js b/public/sw-dev.js new file mode 100644 index 00000000..aa605840 --- /dev/null +++ b/public/sw-dev.js @@ -0,0 +1,51 @@ +// Development Service Worker - simplified version for testing image caching +// This is served in dev mode when vite-plugin-pwa doesn't serve the injectManifest SW + +console.log('[sw-dev] Development Service Worker loaded') + +self.addEventListener('install', (event) => { + console.log('[sw-dev] Installing...') + self.skipWaiting() +}) + +self.addEventListener('activate', (event) => { + console.log('[sw-dev] Activating...') + event.waitUntil(clients.claim()) +}) + +// Image caching - simple version for dev testing +self.addEventListener('fetch', (event) => { + const url = new URL(event.request.url) + const isImage = event.request.destination === 'image' || + /\.(jpg|jpeg|png|gif|webp|svg)$/i.test(url.pathname) + + if (isImage) { + console.log('[sw-dev] Intercepting image:', url.href) + + event.respondWith( + caches.open('boris-images-dev').then((cache) => { + return cache.match(event.request).then((cachedResponse) => { + if (cachedResponse) { + console.log('[sw-dev] ✅ Serving from cache:', url.href) + return cachedResponse + } + + console.log('[sw-dev] Fetching from network:', url.href) + return fetch(event.request).then((response) => { + if (response.ok) { + console.log('[sw-dev] Caching response:', url.href) + cache.put(event.request, response.clone()) + } + return response + }).catch((err) => { + console.error('[sw-dev] Fetch failed:', url.href, err) + throw err + }) + }) + }) + ) + } +}) + +console.log('[sw-dev] Development Service Worker ready') + diff --git a/src/main.tsx b/src/main.tsx index 66d043e2..ec06a05f 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -39,34 +39,34 @@ if ('serviceWorker' in navigator) { } // Not registered yet, try to register - // In dev mode, check if SW file exists and has correct MIME type before registering + // In dev mode, use the dev Service Worker for testing if (import.meta.env.DEV) { + const devSwPath = '/sw-dev.js' + console.log('[sw-registration] Dev mode - using development Service Worker:', devSwPath) try { - const response = await fetch(swPath) + // Check if dev SW exists + const response = await fetch(devSwPath) const contentType = response.headers.get('content-type') || '' const isJavaScript = contentType.includes('javascript') || contentType.includes('application/javascript') - console.log('[sw-registration] Dev mode - checking SW file:', { + console.log('[sw-registration] Dev SW check:', { status: response.status, contentType, - isJavaScript, - isHTML: contentType.includes('text/html') + isJavaScript }) if (response.ok && isJavaScript) { - console.log('[sw-registration] Service Worker file available in dev mode, proceeding with registration') - return await navigator.serviceWorker.register(swPath) + console.log('[sw-registration] Development Service Worker available, proceeding with registration') + return await navigator.serviceWorker.register(devSwPath, { scope: '/' }) } else { - console.warn('[sw-registration] ⚠️ Service Worker file not available in dev mode:', { + console.warn('[sw-registration] ⚠️ Development Service Worker not available:', { status: response.status, contentType }) - console.warn('[sw-registration] Image caching will not work in dev mode - test in production build') return null } } catch (err) { - console.warn('[sw-registration] ⚠️ Could not check Service Worker file in dev mode:', err) - console.warn('[sw-registration] Image caching will not work in dev mode - test in production build') + console.warn('[sw-registration] ⚠️ Could not load development Service Worker:', err) return null } } else { diff --git a/vite.config.ts b/vite.config.ts index 1a0b1829..573fe76f 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -139,7 +139,10 @@ export default defineConfig({ }, devOptions: { enabled: true, - type: 'module' + type: 'module', + // Use generateSW strategy for dev mode to enable SW testing + // This creates a working SW in dev mode, while injectManifest is used in production + navigateFallback: 'index.html' } }) ],