Open JCofman opened 4 years ago
Hi, any updates on this? It's an important topic, not sure what the "official" guidelines are myself.
It's disappointing the Preact service worker doc doesn't seem to cover the info needed to get a simple custom service worker up and running, which states:
"Preact CLI uses InjectManifestPlugin to compile the service worker. This means that in order to use any other workbox module you'll need to install them via NPM and use them in you
src/sw.js
by importing them."
However I get the following error in the browser's console after when running preact watch --sw
:
sw.js:1: Uncaught SyntaxError: Cannot use import statement outside a module
src/sw.js:
import { getFiles, setupPrecaching, setupRouting } from "preact-cli/sw/";
import { registerRoute } from "workbox-routing";
import { NetworkFirst } from "workbox-strategies";
registerRoute(
({ url }) => url.pathname.startsWith("/api/"),
new NetworkFirst()
);
setupRouting();
setupPrecaching(getFiles());
Is the InjectManifestPlugin not actually compiling the service worker?
Hi @JCofman - Preact CLI doesn't actually compile SW during development (preact watch). It serves a debug sw.js that is mainly there to replace any stuck production Service Worker, but that's it.
I think it would be interesting to have the option of enabling the SW generation for dev builds.
The code that does the SW generation (below) will need to be modified to support being injected when preact watch --sw
is used:
https://github.com/preactjs/preact-cli/blob/master/packages/cli/lib/lib/webpack/webpack-client-config.js#L225-L258
Another option might be to have dev mode always use InjectManifestPlugin, even when generating it's basic no-op service worker. That would make it easy to replace the SW with a custom one in a way that works in both dev and prod builds.
@developit thanks for the suggestions! I'm now using the script below in my preact.config.js
which allows my service worker to run with preact watch --sw
. I grabbed this from webpack-client-config.js
and changed a few things to make it work within preact.config.js
. It would be nice however if this was officially supported so if the code gets updated, then mine doesn't get out of sync.
The main issue I'm seeing now is that changing sw.js
triggers a compile due to the watch, however the changes don't get reflected in the service worker. To work around this I rerun preact watch --sw
each time I change my service worker script. This isn't optimal and I don't expect a hot reload because the way service workers function, however running on page refresh is my expectation (unrelated to Chrome's "Update on reload").
When the recompile happens the following is logged on the server:
โผ WARN InjectManifest has been called multiple times, perhaps due to running webpack in --watch mode. The precache manifest generated after the first call may be inaccurate! Please see https://github.com/GoogleChrome/workbox/issues/1790 for more informatibe perhaps due to runon.
I would like to find a way to toggle off the workbox logging when not needed as its very chatty.
import Webpack from "webpack";
import { InjectManifest } from "workbox-webpack-plugin";
import { join } from "path";
import { existsSync } from "fs";
export default function (config, env, helpers) {
if (env.isWatch) {
let swPath;
if (env.sw) {
swPath = join(__dirname, "..", "..", "..", "sw", "sw.js");
const userSwPath = join(env.src, "sw.js");
if (existsSync(userSwPath)) {
swPath = userSwPath;
} else {
console.log(
`Could not find sw.js in ${env.src}. Using the default service worker.`
);
}
}
if (env.esm && env.sw) {
config.plugins.push(
new InjectManifest({
swSrc: swPath,
swDest: "sw-esm.js",
include: [
/^\/?index\.html$/,
/\.esm.js$/,
/\.css$/,
/\.(png|jpg|svg|gif|webp)$/,
],
webpackCompilationPlugins: [
new Webpack.DefinePlugin({
"process.env.ESM": true,
}),
],
})
);
}
if (env.sw) {
config.plugins.push(
new InjectManifest({
swSrc: swPath,
include: [
/index\.html$/,
/\.js$/,
/\.css$/,
/\.(png|jpg|svg|gif|webp)$/,
],
exclude: [/\.esm\.js$/],
})
);
}
}
}
Hi ๐ I had some issues adding a cusotm serviceWorker. I think it would be helpfull to provide some more information on the docs https://preactjs.com/cli/service-worker/ site. I am willing to help :)
Do you want to request a feature or report a bug? Both? :)
What is the current behavior? I am not sure how I can properly debug / update and develop the
serviceWorker
during preact watch. As mentioned in the docs https://preactjs.com/cli/service-worker/ I can write a customsw.js
and add the base functionality from the default preact serviceWorker.When I try to do it like mentioned in the docs I
sw.js
into thesrc
folder and copy paste default code from the docs--sw
preact watch --sw
to include the service worker during development phase (it's currently not mentioned in the referenced docs but I did not find another way otherwise I would get the defaultsw-debug.js
output.preact watch --sw
visiting (0.0.0.0:8080) results in an errorIf the current behaviour is a bug, please provide the steps to reproduce.
mentioned above
What is the expected behaviour? Add an explanation / guide about how to edit serviceWorker behaviour during
preact watch
so that you can customize the default serviceWorker behavior.If this is a feature request, what is motivation or use case for changing the behaviour? Better PWA workflow
Please mention other relevant information.
Please paste the results of
preact info
here.