From 07794367145701a110bf43f918992eeb920a59ba Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Sat, 31 Mar 2018 17:26:10 -0700 Subject: [PATCH] fix service worker webpack assets not being found --- templates/main.js | 4 ++++ templates/service-worker.js | 35 +++++++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/templates/main.js b/templates/main.js index e4fe78ea..d24f7a79 100644 --- a/templates/main.js +++ b/templates/main.js @@ -4,6 +4,10 @@ import '../routes/_utils/serviceWorkerClient' import '../routes/_utils/historyEvents' import '../routes/_utils/loadingMask' +console.log('1') +console.log('2') +console.log('3') + loadPolyfills().then(() => { console.log('init()') // `routes` is an array of route objects injected by Sapper diff --git a/templates/service-worker.js b/templates/service-worker.js index f806331f..bd76c18b 100644 --- a/templates/service-worker.js +++ b/templates/service-worker.js @@ -1,19 +1,21 @@ const timestamp = '__timestamp__' const ASSETS = `assets_${timestamp}` +const WEBPACK_ASSETS = `webpack_assets_${timestamp}` const ON_DEMAND = `ondemand_${timestamp}` // `assets` is an array of everything in the `assets` directory const assets = __assets__ .map(file => file.startsWith('/') ? file : `/${file}`) .filter(filename => !filename.startsWith('/apple-icon')) + .concat(['/index.html']) // `shell` is an array of all the files generated by webpack // also contains '/index.html' for some reason -const resources = __shell__ +const webpackAssets = __shell__ .filter(filename => !filename.endsWith('.map')) + .filter(filename => filename !== '/index.html') -const toCache = [].concat(assets).concat(resources) -const cacheSet = new Set(toCache) +const cacheSet = new Set([].concat(assets).concat(webpackAssets)) // `routes` is an array of `{ pattern: RegExp }` objects that // match the pages in your app @@ -21,8 +23,10 @@ const routes = __routes__ self.addEventListener('install', event => { event.waitUntil((async () => { - let cache = await caches.open(ASSETS) - await cache.addAll(toCache) + await Promise.all([ + caches.open(WEBPACK_ASSETS).then(cache => cache.addAll(webpackAssets)), + caches.open(ASSETS).then(cache => cache.addAll(assets)) + ]) self.skipWaiting() })()) }) @@ -33,11 +37,30 @@ self.addEventListener('activate', event => { // delete old asset/ondemand caches for (let key of keys) { - if (key !== ASSETS && key !== ON_DEMAND) { + if (key !== ASSETS && + key !== ON_DEMAND && + !key.startsWith('webpack_assets_')) { await caches.delete(key) } } + // for webpack assets, keep the two latest builds because we may need + // them when the service worker has installed but the page has not + // yet reloaded (e.g. when it gives the toast saying "please reload" + // but then you don't refresh and instead load an async chunk) + let webpackKeysToDelete = keys + .filter(key => key.startsWith('webpack_assets_')) + .sort((a, b) => { + let aTimestamp = parseInt(a.substring(15), 10) + let bTimestamp = parseInt(b.substring(15), 10) + return bTimestamp < aTimestamp ? -1 : 1 + }) + .slice(2) + + for (let key of webpackKeysToDelete) { + await caches.delete(key) + } + await self.clients.claim() })()) })