How to load a service worker using Webpack 5?

Viewed 5627

I'm using Webpack 5 and I want to have a Service Worker that will intercept fetch requests and return responses locally without hitting the network. I also want to be able to import npm modules within the Service Worker. I used to use a library called serviceworker-webpack-plugin for this purpose, but it's no longer maintained, (and throws errors when I use it). The Webpack docs recommend using Workbox, but this seems to be just for caching assets in the Service Worker, as far as I can gather. Could someone tell me what the correct approach is in 2020 for creating a Service Worker with Webpack 5?

3 Answers

Add the service worker to your webpack.config.js entries field

entry: {
    'app': "./src/index.js",
    'service-worker': "./src/service-worker.ts",
},
output: {
    filename: "[name].js",
},

This will emit dist/app.js and dist/service-worker.js, and it will be possible to import things in both.

serviceworker-webpack-plugin also provides a way for the serviceworker to see a list of all the bundle files it should cache, but that functionality is not available directly and requires making a webpack plugin to get.

Dont overcomplicate it.

You can make an sw work in just 2 steps. Create an sw and register it.

Create an .js file like sw.js and write in it:

self.addEventListener('fetch', function (event) {
  event.respondWith(
    caches.open('mysite-dynamic').then(function (cache) {
      return cache.match(event.request).then(function (response) {
        var fetchPromise = fetch(event.request).then(function (networkResponse) {
          cache.put(event.request, networkResponse.clone());
          return networkResponse;
        });
        return response || fetchPromise;
      });
    }),
  );
});

Thats the stale-while-revalidate approach

Now register it.

if ('serviceWorker' in navigator) {
  window.addEventListener('load', function() {
    navigator.serviceWorker.register('/sw.js').then(function(registration) {
      // Registration was successful
      console.log('ServiceWorker registration successful with scope: ', registration.scope);
    }, function(err) {
      // registration failed :(
      console.log('ServiceWorker registration failed: ', err);
    });
  });
}
Related