question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Switch to Workbox's InjectManifest plugin

See original GitHub issue

Is your proposal related to a problem?

Many want more control over their service worker. The current c-r-a setup uses Workbox’s GenerateSW mode, which uses a declarative webpack configuration to generate the final service worker. Changing the behavior of the service worker therefore requires updating the webpack config, which is not allowed in c-r-a.

Describe the solution you’d like

In Workbox v5, the InjectManifest mode will take an “source” service worker file (either in JavaScript or TypeScript) and run it through a webpack child compilation, which allows you to write your service worker source file just like any other modern JavaScript code, including using ES module imports for the Workbox runtime.

The InjectManifest plugin also takes care of reading the list of assets generated by the webpack compilation and injecting a precache manifest into the service worker file that will precache those assets.

I’d like to switch from GenerateSW to InjectManifest in the c-r-a webpack configuration, and create a new packages/cra-template/template/service-worker.js (and TypeScript equivalent) that roughly contained:

import {clientsClaim} from 'workbox-core';
import {precacheAndRoute, createHandlerBoundToURL} from 'workbox-precaching';
import {registerRoute, NavigationRoute} from 'workbox-routing';

clientsClaim();

precacheAndRoute(self.__WB_MANIFEST);

const handler = createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html');
const navigationRoute = new NavigationRoute(handler, {
  denylist: [
    // Exclude URLs starting with /_, as they're likely an API call
    new RegExp('^/_'),
    // Exclude any URLs whose last part seems to be a file extension
    // as they're likely a resource and not a SPA route.
    // URLs containing a "?" character won't be blacklisted as they're likely
    // a route with query params (e.g. auth callbacks).
    new RegExp('/[^/?]+\\.[^/]+$'),
  ],
});
registerRoute(navigationRoute);

self.addEventListener('message', (event) => {
  if (event.data && event.data.type === 'SKIP_WAITING') {
    self.skipWaiting();
  }
});

This would lead to a service worker that, by default, behaved equivalently to what the previous GenerateSW config created. The benefits are that any part of that service-worker.js could be edited by the end developer, leading to, e.g., custom service worker runtime caching.

I would also like to rename the current packages/cra-template/template/serviceWorker.js file to packages/cra-template/template/serviceWorkerRegistration.js to make it clearer that the file is used in the window context to perform registration, and that it does not include the code for the service worker itself.

In general, giving developers control over their source service worker in this manner should be relatively decoupled from the underlying webpack config. Even if developers made significant changes to their source service worker, by adding in new Workbox modules or other third-party code, the same webpack configuration should still be compatible. The one requirement is that the developer would need to keep the string self.__WB_MANIFEST somewhere in their source service worker file, as InjectManifest checks for this and will fail if it’s not present. (It could be inside of a comment like, e.g. /* self.__WB_MANIFEST */ as a workaround for developers who don’t want to use precaching.)

Describe alternatives you’ve considered

https://github.com/facebook/create-react-app/pull/8822 is an alternative that will just update to Workbox v5.1.2 and keep using the GenerateSW mode, which is okay, but I think developers would be happier if they had the ability to control their service worker. Workbox v5 allows that to be done cleanly in a way that wasn’t possible with prior releases.

Additional context

See https://github.com/facebook/create-react-app/issues/7966 for a similar proposal.

The difference between the two mode is described in more detail at https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin#which_plugin_to_use

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:17
  • Comments:8 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
jeffposnickcommented, Jun 23, 2020

Okay—I’ve filed a PR with the changes discussed above. Based on past experience, I do want to make sure that this isn’t something “rushed” out there to meet to a major release deadline, and I hope the community gets to try out this approach in some prereleases. I obviously trust the judgment of the maintainers 😄

2reactions
mrmckebcommented, Jun 23, 2020

Actually, it’s due very soon I think - @ianschmitz was working on a few last pieces. CC @iansu.

Read more comments on GitHub >

github_iconTop Results From Across the Web

progressive-web-application with webpack.js - Stack Overflow
The InjectManifest plugin will take care of bundling your swSrc file, and it will replace self.__WB_MANIFEST with a precache manifest based ...
Read more >
API Reference - Chrome Developers
Introduction to Workbox and service workers. Service worker overview A service worker's life Strategies for service worker caching What is Workbox?
Read more >
vue-cli-plugin-workbox-pwa - npm
'InjectManifest' (default), allows you to start with an existing service worker file, and creates a copy of that file with a "precache manifest" ......
Read more >
Advanced (injectManifest) | Guide | Vite PWA - Netlify
The vite-plugin-pwa plugin will compile your custom service worker ... If you want to change the location and/or the service worker name, ...
Read more >
How to Generate Service Workers Automatically
There are two sub plugins implemented as modules within the workbox-webpack-plugin named GenerateSW and InjectManifest.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found