From e7dfab4cb22b8031322d38f5b5be4e9460ff9220 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Mon, 3 Feb 2020 12:12:40 -0800 Subject: [PATCH] Update service worker script to only serve up HTML of root route as an offline fallback. --- generator/src/develop.js | 2 +- generator/src/service-worker-template.js | 70 ++++++++++++------------ 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/generator/src/develop.js b/generator/src/develop.js index 8615236d..10142ad3 100644 --- a/generator/src/develop.js +++ b/generator/src/develop.js @@ -212,7 +212,7 @@ function webpackOptions( }), new InjectManifest({ swSrc: path.resolve(__dirname, "./service-worker-template.js"), - include: [/^index\.html$/], + include: [/^index\.html$/, /main\.js$/], exclude: [ /android-chrome-.*\.png$/, /apple-touch-icon.*\.png/, diff --git a/generator/src/service-worker-template.js b/generator/src/service-worker-template.js index 70e8971d..a4848bfe 100644 --- a/generator/src/service-worker-template.js +++ b/generator/src/service-worker-template.js @@ -1,12 +1,42 @@ workbox.core.skipWaiting(); workbox.core.clientsClaim(); workbox.precaching.precacheAndRoute(self.__precacheManifest); -workbox.routing.registerNavigationRoute( - workbox.precaching.getCacheKeyForURL("/index.html"), - { - blacklist: [/admin/, /\./] + + +// This section is based on the following workbox recipe: +// https://developers.google.com/web/tools/workbox/guides/advanced-recipes#provide_a_fallback_response_to_a_route +const CACHE_NAME = 'shell'; +const FALLBACK_HTML_URL = '/index.html'; + + +self.addEventListener('install', async (event) => { + event.waitUntil( + caches.open(CACHE_NAME) + .then((cache) => cache.add(FALLBACK_HTML_URL)) + ); +}); + + +const networkOnly = new workbox.strategies.NetworkOnly(); +const navigationHandler = async (params) => { + try { + // Attempt a network request. + return await networkOnly.handle(params); + } catch (error) { + // If it fails, return the cached HTML. + // workbox.precaching.getCacheKeyForURL("/index.html") + // return caches.match(workbox.precaching.getCacheKeyForURL("/index.html")); + return caches.match('/index.html', { + cacheName: CACHE_NAME, + }); } +}; + +// Register this strategy to handle all navigations. +workbox.routing.registerRoute( + new workbox.routing.NavigationRoute(navigationHandler) ); + workbox.routing.registerRoute( /^https:\/\/fonts\.gstatic\.com/, new workbox.strategies.CacheFirst({ @@ -15,14 +45,6 @@ workbox.routing.registerRoute( }), "GET" ); -workbox.routing.registerRoute( - /.js$/, - new workbox.strategies.NetworkFirst({ - cacheName: "shell", - plugins: [] - }), - "GET" -); workbox.routing.registerRoute( /^https:\/\/fonts\.googleapis\.com/, new workbox.strategies.StaleWhileRevalidate({ @@ -41,30 +63,10 @@ workbox.routing.registerRoute( ); workbox.routing.registerRoute( - /content\.txt$/, + /content\.json/, new workbox.strategies.NetworkFirst({ cacheName: "content", plugins: [] }), "GET" -); - -self.addEventListener("install", event => { - // TODO load the list of content files to warm up in the cache here - - // TODO store content in a cache that is hashed based on the webpack bundle hash, - // then delete the old cache on activate - const contentUrls = [ - // "/blog/content.json", - // "/blog/types-over-conventions/content.json" - ]; - const coreUrls = ["/main.js"]; - const preloadContent = caches - .open("content") - .then(cache => cache.addAll(contentUrls)); - const preloadCore = caches - .open("shell") - .then(cache => cache.addAll(coreUrls)); - const warmUp = Promise.all([preloadContent, preloadCore]); - return warmUp; -}); +); \ No newline at end of file