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.
This commit is contained in:
Gigi
2025-10-31 01:10:20 +01:00
parent 851cecf18c
commit cfa6dc4400
3 changed files with 66 additions and 12 deletions

51
public/sw-dev.js Normal file
View File

@@ -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')

View File

@@ -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 {

View File

@@ -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'
}
})
],