javascriptwebpackfrontendservice-workerworkbox

service worker generated by workbox-build comes error require is not defined


I'm using workbox-build to generate sw.js for my web application, here is the build script named build-sw.js:

const { injectManifest } = require('workbox-build');

// These are some common options, and not all are required.
// Consult the docs for more info.
injectManifest({
  dontCacheBustURLsMatching: /...../,
  globDirectory: './dist',
  globPatterns: [
    '**/*.js',
    '**/*.css',
    '**/*.svg'
  ],
  swDest: './dist/sw.js',
  swSrc: './sw-inject-source.js',
}).then(({count, size, warnings}) => {
  if (warnings.length > 0) {
    console.warn(
      'Warnings encountered while injecting the manifest:',
      warnings.join('\n')
    );
  }

  console.log(`Injected a manifest which will precache ${count} files, totaling ${size} bytes.`);
});

and here is the source code to generate sw.js named sw-inject-source.js:

const { precacheAndRoute } = require('workbox-precaching/precacheAndRoute');
const { registerRoute } = require('workbox-routing');
const { StaleWhileRevalidate } = require('workbox-strategies');


precacheAndRoute(self.__WB_MANIFEST);

registerRoute(
    new RegExp('https://dog.ceo/api/breeds/image/random'),
    new StaleWhileRevalidate({
        cacheName: 'apiCache',
    })
);

But after I deploy the sw.js online, the sw.js comes the error:

require is not defined.

It seems like that the module import code in sw-inject-source.js causes this error, I have no idea to fix this, could you please give some advices?


Solution

  • I realize this is an old question, but as I came across the same problem and I think I have spotted the right track, I figured I'd write it here so that others can benefit.

    Key aspect: require belongs to the Node.js (server-side) Javascript, but you are trying to build a JS file that will need to run in a web browser(!). That's the source of all misunderstanding.

    This video that explains how they do it at Google will put you on the right track of the extra steps/tools that are needed.

    https://www.youtube.com/watch?v=sOq92prx00w&t=419s&ab_channel=GoogleChromeDevelopers

    Now this Jeff guy is compiling TypeScript, but there are other tools that can bring you from Node's JavaScript to browsers' JavaScript.

    One thing is for sure: this worker thing is super convoluted. Information is scattered all over the place, old info is getting in the way, and there's a ton of info to absorb before one starts making sense of it all.

    As far as I am concerned, I gave up trying to "convert" and I fell back to the solution that imports workbox from the CDN as a script:

    importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
    );
    
    const {precacheAndRoute} = workbox.precaching
    const {registerRoute} = workbox.routing
    const {CacheFirst} = workbox.strategies
    const {CacheableResponse} = workbox.cacheableResponse
    
    // This will be replaced by the list of files to precache by
    // the `workbox injectManifest` build step.
    const manifest = self.__WB_MANIFEST;
    precacheAndRoute(manifest);