I am creating a React App using the Create React App utility and I want to override the default service worker that it provides.
Since I don't want to eject my app, I am using the workbox-build
package to create my service worker (I also used yarn to install the workbox-sw
package).
My service worker code is the following:
/* eslint-disable no-restricted-globals */
import * as core from 'workbox-core';
import * as routing from 'workbox-routing';
import * as strategies from 'workbox-strategies';
import * as precaching from 'workbox-precaching';
self.addEventListener('message', event => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
core.clientsClaim();
routing.registerRoute(
new RegExp('^'),
new strategies.StaleWhileRevalidate({
cacheName: 'google-fonts-stylesheets-v1',
})
);
precaching.precacheAndRoute([]);
routing.registerNavigationRoute(
precaching.getCacheKeyForURL('/index.html'), {
blacklist: [/^\/_/, /\/[^/?]+\.[^/]+$/],
}
);
And my workbox-build
script is:
const workboxBuild = require('workbox-build');
// NOTE: This should be run *AFTER* all your assets are built
const buildSW = () => {
// This will return a Promise
return workboxBuild.injectManifest({
swSrc: 'src/service-worker.js',
swDest: 'build/service-worker.js',
globDirectory: 'build',
globPatterns: [
'**\/*.{js,css,html,png,json}',
]
}).then(({
count,
size,
warnings
}) => {
// Optionally, log any warnings and details.
warnings.forEach(console.warn);
console.log(`${count} files will be precached, totaling ${size} bytes.`);
});
}
buildSW();
For registering the service worker I am using:
import { Workbox } from 'workbox-window';
export function register() {
if ('serviceWorker' in navigator) {
const wb = new Workbox('/service-worker.js');
wb.register();
}
}
However when I run my App I get these errors:
service-worker.js:2 Uncaught SyntaxError: Cannot use import statement outside a module
:3000/107/aggregator:1 Uncaught (in promise) TypeError: Failed to register a ServiceWorker for scope ('http://localhost:3000/') with script ('http://localhost:3000/service-worker.js'): ServiceWorker script evaluation failed
What am I doing wrong?
I am creating a React App using the Create React App utility and I want to override the default service worker that it provides.
Since I don't want to eject my app, I am using the workbox-build
package to create my service worker (I also used yarn to install the workbox-sw
package).
My service worker code is the following:
/* eslint-disable no-restricted-globals */
import * as core from 'workbox-core';
import * as routing from 'workbox-routing';
import * as strategies from 'workbox-strategies';
import * as precaching from 'workbox-precaching';
self.addEventListener('message', event => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
core.clientsClaim();
routing.registerRoute(
new RegExp('^https://fonts.googleapis.com'),
new strategies.StaleWhileRevalidate({
cacheName: 'google-fonts-stylesheets-v1',
})
);
precaching.precacheAndRoute([]);
routing.registerNavigationRoute(
precaching.getCacheKeyForURL('/index.html'), {
blacklist: [/^\/_/, /\/[^/?]+\.[^/]+$/],
}
);
And my workbox-build
script is:
const workboxBuild = require('workbox-build');
// NOTE: This should be run *AFTER* all your assets are built
const buildSW = () => {
// This will return a Promise
return workboxBuild.injectManifest({
swSrc: 'src/service-worker.js',
swDest: 'build/service-worker.js',
globDirectory: 'build',
globPatterns: [
'**\/*.{js,css,html,png,json}',
]
}).then(({
count,
size,
warnings
}) => {
// Optionally, log any warnings and details.
warnings.forEach(console.warn);
console.log(`${count} files will be precached, totaling ${size} bytes.`);
});
}
buildSW();
For registering the service worker I am using:
import { Workbox } from 'workbox-window';
export function register() {
if ('serviceWorker' in navigator) {
const wb = new Workbox('/service-worker.js');
wb.register();
}
}
However when I run my App I get these errors:
service-worker.js:2 Uncaught SyntaxError: Cannot use import statement outside a module
:3000/107/aggregator:1 Uncaught (in promise) TypeError: Failed to register a ServiceWorker for scope ('http://localhost:3000/') with script ('http://localhost:3000/service-worker.js'): ServiceWorker script evaluation failed
What am I doing wrong?
Share Improve this question asked Dec 10, 2019 at 16:54 FelipeFelipe 7,39113 gold badges58 silver badges75 bronze badges2 Answers
Reset to default 7Current Answer
According to Mozilla's documentation it should work now, but keep an eye on the up-to-date implementation status in each browser. Firefox and Opera (implemented since Version 67) are still behind.
Mozilla is going to implement that feature in Firefox 114.
Original answer from 2020
There is no module support in workers yet.
importScripts() could do the job for you, but it can not import modules, meaning anything with an "export" keyword inside.
https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts
fips' answer helped me get on the right track.
I am not using a bundler/compiler. A bundler/compiler seems like a the avenue to pursue.
However, for anyone else that this may help:
importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.5.3/workbox-sw.js');
workbox.precaching.precacheAndRoute(self.__WB_MANIFEST);
fits well to those trying to solve some examples from Googles documentation
or more specific to your code, all those modules are accessible as attributes on the workbox
object.
importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.5.3/workbox-sw.js');
self.addEventListener('message', event => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
workbox.core.clientsClaim();
workbox.routing.registerRoute(/* your params here */);
workbox.precaching.precacheAndRoute(/* your params here */);
// presuming OP function is deprecated in current version and changed
// to 'registerRoute', but may actually be 'NavigationRoute' check
// current documentation for more clarity.
workbox.routing.registerRoute(/* your params here */);