service worker enhancements

This commit is contained in:
keyan 2023-07-29 14:33:19 -05:00
parent 688d67a0d6
commit de089aa429
3 changed files with 45 additions and 15 deletions

View File

@ -136,19 +136,34 @@ module.exports = withPlausibleProxy()({
} }
] ]
}, },
webpack: (config, { isServer }) => { webpack: (config, { isServer, dev }) => {
if (isServer) { if (isServer) {
generatePrecacheManifest() generatePrecacheManifest()
config.plugins.push( const workboxPlugin = new InjectManifest({
new InjectManifest({ // ignore the precached manifest which includes the webpack assets
// ignore the precached manifest which includes the webpack assets // since they are not useful to us
// since they are not useful to us exclude: [/.*/],
exclude: [/.*/], // by default, webpack saves service worker at .next/server/
// by default, webpack saves service worker at .next/server/ swDest: '../../public/sw.js',
swDest: '../../public/sw.js', swSrc: './sw/index.js'
swSrc: './sw/index.js' })
if (dev) {
// Suppress the "InjectManifest has been called multiple times" warning by reaching into
// the private properties of the plugin and making sure it never ends up in the state
// where it makes that warning.
// https://github.com/GoogleChrome/workbox/blob/v6/packages/workbox-webpack-plugin/src/inject-manifest.ts#L260-L282
Object.defineProperty(workboxPlugin, 'alreadyCalled', {
get () {
return false
},
set () {
// do nothing; the internals try to set it to true, which then results in a warning
// on the next run of webpack.
}
}) })
) }
config.plugins.push(workboxPlugin)
} }
return config return config
} }

View File

@ -32,7 +32,6 @@ function generatePrecacheManifest () {
const staticDir = join(__dirname, '../public') const staticDir = join(__dirname, '../public')
const staticFiles = walkSync(staticDir) const staticFiles = walkSync(staticDir)
console.log(staticFiles)
const staticMatch = f => [/\.(gif|jpe?g|ico|png|ttf|woff|woff2|webmanifest)$/].some(m => m.test(f)) const staticMatch = f => [/\.(gif|jpe?g|ico|png|ttf|woff|woff2|webmanifest)$/].some(m => m.test(f))
staticFiles.filter(staticMatch).forEach(file => { staticFiles.filter(staticMatch).forEach(file => {
const stats = statSync(file) const stats = statSync(file)

View File

@ -3,11 +3,20 @@ import { precacheAndRoute } from 'workbox-precaching'
import { offlineFallback } from 'workbox-recipes' import { offlineFallback } from 'workbox-recipes'
import { setDefaultHandler } from 'workbox-routing' import { setDefaultHandler } from 'workbox-routing'
import { NetworkOnly } from 'workbox-strategies' import { NetworkOnly } from 'workbox-strategies'
import { enable } from 'workbox-navigation-preload'
import manifest from './precache-manifest.json' import manifest from './precache-manifest.json'
// preloading improves startup performance
// https://developer.chrome.com/docs/workbox/modules/workbox-navigation-preload/
enable()
// uncomment to disable workbox console logs
// self.__WB_DISABLE_DEV_LOGS = true
// ignore precache manifest generated by InjectManifest // ignore precache manifest generated by InjectManifest
// they statically check for the presence of this variable // they statically check for the presence of this variable
console.log(self.__WB_MANIFEST) console.log(self.__WB_MANIFEST)
precacheAndRoute(manifest) precacheAndRoute(manifest)
self.addEventListener('install', () => { self.addEventListener('install', () => {
@ -18,7 +27,14 @@ self.addEventListener('install', () => {
// to the browser as if the service worker wouldn't exist. // to the browser as if the service worker wouldn't exist.
// The browser may use own caching (HTTP cache). // The browser may use own caching (HTTP cache).
// Also, the offline fallback only works if request matched a route // Also, the offline fallback only works if request matched a route
setDefaultHandler(new NetworkOnly()) setDefaultHandler(new NetworkOnly({
// tell us why a request failed in dev
plugins: [{
fetchDidFail: async (args) => {
process.env.NODE_ENV !== 'production' && console.log('fetch did fail', ...args)
}
}]
}))
// This won't work in dev because pages are never cached. // This won't work in dev because pages are never cached.
// See https://github.com/vercel/next.js/blob/337fb6a9aadb61c916f0121c899e463819cd3f33/server/render.js#L181-L185 // See https://github.com/vercel/next.js/blob/337fb6a9aadb61c916f0121c899e463819cd3f33/server/render.js#L181-L185
@ -72,6 +88,7 @@ self.addEventListener('pushsubscriptionchange', (event) => {
id id
} }
}` }`
const subscription = self.registration.pushManager const subscription = self.registration.pushManager
.subscribe(event.oldSubscription.options) .subscribe(event.oldSubscription.options)
.then((subscription) => { .then((subscription) => {
@ -92,7 +109,6 @@ self.addEventListener('pushsubscriptionchange', (event) => {
body body
}) })
}) })
event.waitUntil(subscription) event.waitUntil(subscription)
}, }, false)
false
)