Workbox

Workbox – A tool from Google to set up a service worker.

I already wrote about how to configure a service worker.

The methods described in that article help to configure the service worker, but at the same time setting it up manually, you will have to solve all the difficulties with the cache yourself.

WorkBox is a library or if you want a framework for PWA. It helps to configure the service worker so that you have full control over all work with the cache.

This article will describe how to configure the service worker version 3.6.1. The current version is the 5th and it works a little differently. However, 3.6.1 copes with this task. And since I have not yet created on another version, I will describe the process on version 3.6.1.

Workbox setup

Download the workbox and put it inside the file sw.js:

// Workbox from google
var workbox=function(){“use strict”;try{self.workbox.v[[“workbox: sw: 3.6.1”]=1}catch(t){}const t=“https://storage.googleapis.com/workbox-cdn/releases/3.6.1”,e={backgroundSync:“background-sync”,broadcastUpdate:“broadcast-cache-update”,cacheableResponse:“cacheable-response”,core:“core”,expiration:“cache-expiration”,googleAnalytics:“google-analytics”,navigationPreload:“navigation-preload”,precaching:“precaching”,rangeRequests:“range-requests”,routing:“routing”,strategies:“strategies”,streams:“streams”};return new class{constructor(){return this.v={},this.t={debug:“localhost”===self.location.hostname,modulePathPrefix:null,modulePathCb:null},this.e=this.t.debug?“dev”:“prod”,this.s=!1,new Proxy(this,{get(t,s){if(t[[s])return t[[s];const o=e[[s];return o&&t.loadModule(`workbox${o}`),t[[s]}})}setConfig(t={}){if(this.s)throw new Error(“Config must be set before accessing workbox. * Modules”);Object.assign(this.t,t),this.e=this.t.debug?“dev”:“prod”}skipWaiting(){self.addEventListener(“install”,()=>self.skipWaiting())}clientsClaim(){self.addEventListener(“activate”,()=>self.clients.claim())}loadModule(t){const e=this.o(t);try{importScripts(e),this.s=!0}catch(s){throw console.error(`Unable to import module ‘$ {t}’ from ‘$ {e}’.`),s}}o(e){if(this.t.modulePathCb)return this.t.modulePathCb(e,this.t.debug);let s=[[t];const o=`${e}. ${this.e}.js`,r=this.t.modulePathPrefix;return r&&“”===(s=r.split(“/”))[[s.length1]&&s.splice(s.length1,1),s.push(o),s.join(“/”)}}}();

Further in the same file inside the construct:

Add files that will be responsible for offline mode and 404 pages:

const versionPrecache = 1;
workbox.precaching.precacheAndRoute([[
{
“url”: “pwa-offline.html”,
“revision”: versionPrecache
},
{
“url”: “pwa-404.html”,
“revision”: versionPrecache
}
]);

Cache images

Then there are several spellings of what to put in the cache, for example:

workbox.routing.registerRoute(
/(.*).(?:png|gif|jpg)(.*)/,
workbox.strategies.networkFirst({
cacheName: ‘images’,
plugins: [[
new workbox.cacheableResponse.Plugin({
statuses: [[0, 200]
}),
new workbox.expiration.Plugin({
maxEntries: 100,
maxAgeSeconds: 60 * 60 * 24 * 7,
purgeOnQuotaError: true
})
]
})
);

With this we created a group imagestook advantage of the strategy networkFirst.

The networkFirst strategy is a strategy in which the contents in the cache will be updated if something has changed on the site. If there is no access to online, then content from the cache will be taken.

Use purgeOnQuotaErrorso that if the data storage quota is exceeded, clear the contents of the cache.

Indicate maxEntries – how many items to store in the cache and number in seconds maxAgeSeconds.

When the time specified in maxAgeSeconds expires, the cache is deleted, even if the application is not online.

cacheableResponse – says that to keep only that which gives us the status of 200.

We cache the main

const mainHandler = workbox.strategies.networkFirst({
cacheName: ‘main’,
plugins: [[
new workbox.cacheableResponse.Plugin({
statuses: [[0, 200]
}),
new workbox.expiration.Plugin({
maxEntries: 50,
maxAgeSeconds: 60 * 60 * 24 * 3,
purgeOnQuotaError: true
})
]
});

workbox.routing.registerRoute(/^https://ploshadka.(net|net/)$/, args => {
return mainHandler.handle(args).then(response => {
if (!response) {
return caches.match(‘pwa-offline.html’);
} else if (response.status === 404) {
return caches.match(‘pwa-404.html’);
}
return response;
});
});

In this post, we are talking about putting the main page in a separate group. If it is not cached, we will show the page offline – pwa-offline.html.

By analogy, we do for the rest.

The principle of caching – caching goes from top to bottom. If it falls into the first groups, then it does not fall further.

Since all pages are often difficult to take into account, I recommend creating a group for everything and putting this code at the end of the file:

const allOtherHandler = workbox.strategies.networkFirst({
cacheName: ‘other’,
plugins: [[
new workbox.cacheableResponse.Plugin({
statuses: [[0, 200]
}),
new workbox.expiration.Plugin({
maxEntries: 100,
maxAgeSeconds: 60 * 60 * 24,
purgeOnQuotaError: true
})
]
});

workbox.routing.registerRoute(/(.*)/, args => {
return allOtherHandler.handle(args).then(response => {
if (!response) {
return caches.match(‘pwa-offline.html’);
} else if (response.status === 404) {
return caches.match(‘pwa-404.html’);
}
return response;
});
});

Then any page will display the pwa-offline.html page offline.

Install Service Worker

We will need another file that will install everything that we wrote above.

Name this file sw-setup.js.

const DEBUG = true;

// Change the file version when changing the service worker
const serviceWorkerVer = “/sw.js?v=1”;

var url = window.location.origin,
fullUrl = url + serviceWorkerVer;

+ function installServiceWorker () {
if (“serviceWorker” in navigator) {
window.addEventListener (‘load’, () => {

if (navigator.serviceWorker.controller! == null) {
DEBUG && console.log (“[SW] The current version in the browser is “+ navigator.serviceWorker.controller.scriptURL);
DEBUG && console.log (“[SW] New version “+ fullUrl);
}

if (navigator.serviceWorker.controller === null) {
registrationServiceWorker (navigator.serviceWorker);

} else if (
navigator.serviceWorker.controller.scriptURL! == fullUrl) {

removeServiceWorker (navigator.serviceWorker);

removeCache (‘workbox-precache-v2-‘ + url + ‘/’);
removeCache (‘workbox-precache-‘ + url + ‘/’);
removeCache (‘workbox-precache-‘ + url + ‘/ -temp’);
removeCache (‘workbox-precache’);
removeCache (‘images’);
removeCache (‘main’);
removeCache (‘other’);

} else {
DEBUG && console.log (“[SW] Active service worker latest version found, do not re-register “);
}
});
}
} ();

// Register Service Worker
function registrationServiceWorker (navigatorServiceWorker) {
navigatorServiceWorker
.register (serviceWorkerVer)
.then (reg => {
DEBUG && console.log (`[SW] Service worker registered for address (scope): $ {reg.scope} `);
})
.catch (err => {
DEBUG && console.log (`[SW] An error occurred while registering the service worker: $ {err} `);
});
}

// Removing service worker
function removeServiceWorker (navigatorServiceWorker) {
navigatorServiceWorker.getRegistrations ()
.then (function (registrations) {
for (var registration of registrations) {
registration.unregister ();
DEBUG && console.log (“[SW] The previous version of the service worker was successfully removed “);
DEBUG && console.log (“[SW] ! To install the new version, reload the page “);
}
}
);
}

// Clear the cache
function removeCache (cache) {
caches.delete (cache) .then (function (boolean) {
DEBUG && console.log (“[SW] Cache “+ cache +” cleared “);
});
}

Minifest file

About him is already in this article. It must be repeated.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *