diff --git a/.changeset/thin-horses-bake.md b/.changeset/thin-horses-bake.md new file mode 100644 index 00000000000..bd9d2bcde02 --- /dev/null +++ b/.changeset/thin-horses-bake.md @@ -0,0 +1,7 @@ +--- +'@builder.io/qwik-city': patch +--- + +FIX: Your service-worker.js won't be unregistered anymore if you added custom logic to it. + +> Note: Qwik 1.14.0 and above now use `` by default. If you didn't add custom service-worker logic, you should remove your service-worker.ts file(s) for the `ServiceWorkerRegister` Component to actually unregister the service-worker.js and delete its related cache. Make sure to keep the `ServiceWorkerRegister` Component in your app (without any service-worker.ts file) as long as you want to unregister the service-worker.js for your users. diff --git a/packages/qwik-city/src/buildtime/runtime-generation/generate-service-worker.ts b/packages/qwik-city/src/buildtime/runtime-generation/generate-service-worker.ts index 1f9209a43ce..5f291122507 100644 --- a/packages/qwik-city/src/buildtime/runtime-generation/generate-service-worker.ts +++ b/packages/qwik-city/src/buildtime/runtime-generation/generate-service-worker.ts @@ -2,30 +2,48 @@ import type { BuildContext } from '../types'; export function generateServiceWorkerRegister(ctx: BuildContext, swRegister: string) { let swReg: string; + let swUrl = '/service-worker.js'; - if (ctx.isDevServer) { + // Also unregister if the developer removed the service-worker.ts file since Qwik 1.14.0 and above now use modulepreload by default + if (ctx.isDevServer || ctx.serviceWorkers.length === 0) { swReg = SW_UNREGISTER; } else { swReg = swRegister; - let swUrl = '/service-worker.js'; - if (ctx.serviceWorkers.length > 0) { - const sw = ctx.serviceWorkers.sort((a, b) => - a.chunkFileName.length < b.chunkFileName.length ? -1 : 1 - )[0]; - swUrl = ctx.opts.basePathname + sw.chunkFileName; - } - - swReg = swReg.replace('__url', swUrl); + const sw = ctx.serviceWorkers.sort((a, b) => + a.chunkFileName.length < b.chunkFileName.length ? -1 : 1 + )[0]; + swUrl = ctx.opts.basePathname + sw.chunkFileName; } + swReg = swReg.replace('__url', swUrl); return `export default ${JSON.stringify(swReg)};`; } const SW_UNREGISTER = ` -navigator.serviceWorker?.getRegistrations().then((regs) => { - for (const reg of regs) { - reg.unregister(); - } -}); +"serviceWorker"in navigator&&navigator.serviceWorker.getRegistrations().then(r=>{for(const e of r){const c='__url'.split("/").pop();e.active?.scriptURL.endsWith(c||"service-worker.js")&&e.unregister().catch(console.error)}}),"caches"in window&&caches.keys().then(r=>{const e=r.find(c=>c.startsWith("QwikBuild"));e&&caches.delete(e).catch(console.error)}).catch(console.error) `; +// Code in SW_UNREGISTER unregisters the service worker and deletes the cache; it is the minified version of the following: +// (() => { +// if ('serviceWorker' in navigator) { +// navigator.serviceWorker.getRegistrations().then((regs) => { +// for (const reg of regs) { +// const url = '__url'.split('/').pop(); +// if (reg.active?.scriptURL.endsWith(url || 'service-worker.js')) { +// reg.unregister().catch(console.error); +// } +// } +// }); +// } +// if ('caches' in window) { +// caches +// .keys() +// .then((names) => { +// const cacheName = names.find((name) => name.startsWith('QwikBuild')); +// if (cacheName) { +// caches.delete(cacheName).catch(console.error); +// } +// }) +// .catch(console.error); +// } +// })(); diff --git a/packages/qwik-city/src/buildtime/vite/plugin.ts b/packages/qwik-city/src/buildtime/vite/plugin.ts index 880e5d22a9c..e9d0d2ae287 100644 --- a/packages/qwik-city/src/buildtime/vite/plugin.ts +++ b/packages/qwik-city/src/buildtime/vite/plugin.ts @@ -191,6 +191,7 @@ function qwikCityPlugin(userOpts?: QwikCityVitePluginOptions): any { } } } + return null; }, diff --git a/packages/qwik-city/src/runtime/src/sw-component.tsx b/packages/qwik-city/src/runtime/src/sw-component.tsx index 2aa9bbd8c0c..8b020818708 100644 --- a/packages/qwik-city/src/runtime/src/sw-component.tsx +++ b/packages/qwik-city/src/runtime/src/sw-component.tsx @@ -5,6 +5,12 @@ import type { JSXOutput } from '@builder.io/qwik'; * JS extensions are allowed) will be picked up, bundled into a separate file, and registered as a * service worker. * + * Qwik 1.14.0 and above now use `` by default. If you didn't add custom + * service-worker logic, you should remove your service-worker.ts file(s) for the + * `ServiceWorkerRegister` Component to actually unregister the service-worker.js and delete its + * related cache. Make sure to keep the `ServiceWorkerRegister` Component in your app (without any + * service-worker.ts file) as long as you want to unregister the service-worker.js for your users. + * * @public */ export const ServiceWorkerRegister = (props: { nonce?: string }): JSXOutput => ( diff --git a/packages/qwik-city/src/runtime/src/sw-register.ts b/packages/qwik-city/src/runtime/src/sw-register.ts index 8df878bc83c..89b19fecefa 100644 --- a/packages/qwik-city/src/runtime/src/sw-register.ts +++ b/packages/qwik-city/src/runtime/src/sw-register.ts @@ -2,24 +2,21 @@ (() => { if ('serviceWorker' in navigator) { - navigator.serviceWorker.getRegistrations().then((regs) => { - for (const reg of regs) { - const url = '__url'.split('/').pop(); - if (reg.active?.scriptURL.endsWith(url || 'service-worker.js')) { - reg.unregister().catch(console.error); - } - } - }); - } - if ('caches' in window) { - caches - .keys() - .then((names) => { - const cacheName = names.find((name) => name.startsWith('QwikBuild')); - if (cacheName) { - caches.delete(cacheName).catch(console.error); - } - }) - .catch(console.error); + navigator.serviceWorker.register('__url').catch((e) => console.error(e)); + // We need to delete the cache since we are using modulepreload by default in qwik 1.14 and above + if ('caches' in window) { + caches + .keys() + .then((names) => { + const cacheName = names.find((name) => name.startsWith('QwikBuild')); + if (cacheName) { + caches.delete(cacheName).catch(console.error); + } + }) + .catch(console.error); + } + } else { + // eslint-disable-next-line no-console + console.log('Service worker not supported in this browser.'); } })();