Big things to demo:
- Using the config approach to precaching
- Template service worker
- Runtime caching of external resources
- Caching strategies
- Caching of SSR stuff.
- Background sync and replay
- Streams API.
- Start of with a simple polymer app.
- Build it.
- Install workbox
- Run Workbox wizard to generate config.
- Install service worker.
>> npm install -g workbox-cli
We can generate a service worker using workbox
>> workbox wizard
? What is the root of your web app (i.e. which directory do you deploy)? dist/
? Which file types would you like to precache? txt, png, ico, html, js, json, css
? Where would you like your service worker file to be saved? dist/sw.js
? Where would you like to save these configuration options? workbox-config.js
Update the directory to build/default/
module.exports = {
"globDirectory": "build/default",
"globPatterns": [
"**/*.{html,js}"
],
"swDest": "build/default/sw.js"
};
Install the sw.js
and rebuild
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('sw.js');
}
</script>
Generate the service worker.
>> workbox generateSW workbox-config.js
- Create a templated service worker.
- Create the injection point.
- Install libraries.
- Inject manifest.
A more powerful way to do this is not via config alone, but a template sw.js
.
importScripts("https://storage.googleapis.com/workbox-cdn/releases/3.6.2/workbox-sw.js");
const precacheManifest = [];
workbox.precaching.suppressWarnings();
workbox.precaching.precacheAndRoute(precacheManifest);
Change the config to respect the inject manifest.
"swSrc": "src/sw.js",
"injectionPointRegexp": /(const precacheManifest = )\[\](;)/
>> workbox injectManifest workbox-config.js
>> http-server build/default/ -c 0
workbox.routing.registerRoute(
/\.(?:png|gif|jpg|jpeg|svg)$/,
workbox.strategies.cacheFirst({
cacheName: 'images'
}),
);
plugins: [
new workbox.expiration.Plugin({
maxEntries: 60,
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
}),
]
Use staleWhileRevalidate for the JSON data.
workbox.routing.registerRoute(
/\.json$/,
workbox.strategies.staleWhileRevalidate({
cacheName: 'data'
}),
);
Run workbox wizard
in the root of the site, using wwwroot
as the directory.
Install it in _Layout.cshtml
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('sw.js');
}
</script>
self.addEventListener('install', (event) => {
console.log('Service worker is being installed.');
});
const channel = new BroadcastChannel('service-worker-channel');
channel.postMessage({ promptToReload: true });
const channel = new BroadcastChannel('service-worker-channel');
channel.onmessage = (message) => {
if (message.data.promptToReload) {
if (confirm('Updates available. Would you like to reload?')) {
channel.postMessage({ skipWaiting: true });
};
}
}
channel.onmessage = (message) => {
if (message.data.skipWaiting) {
console.log('Skipping waiting and installing service worker.');
self.skipWaiting();
}
};
navigator.serviceWorker.addEventListener('controllerchange', () => {
window.location.reload();
});
const queue = new workbox.backgroundSync.Queue('pending-orders');
self.addEventListener('fetch', (event) => {
if (event.request.method === 'POST' && event.request.url.match(/.*orders/)) {
let response = fetch(event.request.clone())
.catch((err) => {
return queue.addRequest(event.request.clone())
.then(() => new Response(JSON.stringify({ success: true }), { status: 200 }))
});
event.respondWith(response);
}
});
???