Do you want to request a _feature_ or report a _bug_?
Question
What is the current behaviour?
In V3 we moved from SwPrecache to Workobx jS.
While moving we added a functionality to be able to create both module/nomodule service worker from the same source service worker file defined here.
This uses InjectManifest plugin from Workbox which injects precache file in a handwritten service worker.
This also gives us extra functionality to do brotli/webP redirect whenever user opts in.
While all this is great, any additional changes to the service worker needs to be done in code instead of changing some config in v2.
I just wonder if that might come across as a tougher choice for the users and whether we should just stick to the config based GenerateSwWebpackPlugin from Workbox and may be write blogs/wiki on how to do the brotli/webP with preact-cli.
// @developit @hassanbazzi @ForsakenHarmony @lukeed
was it easy to customise it before?
ideally it'd be easy to extend, not just replace the service worker
and we could maybe add options to preact.config.js
Its like with current setup you need to write code to change the functionality, vs in earlier setup you needed to change config of plugin.
I guess its just more tough for ppl to write code for SWs, thats why i opened this issue
If we agree that this is the case #819 will fix it
yeah I don't like modifying config of existing plugins in preact.config.js I'd rather have something more intuitive
@ForsakenHarmony just to confirm, so you feel writing workbox code for your service worker would be more intuitive than editing an object in preact.config.js?
just a nit, our users would need to learn workbox APIs to stuff like runtime caching etc vs adding them in config.
No I'm saying changing to a differnt plugin and not changing our public api (I don't count modifying the webpack config) doesn't change anything
Ok a quick show of hands please to sort this out
Reply on this comment with 馃憤 / 馃憥
馃憤 - Yes lets shift to config based service worker generator as is done in next/nuxt/gatsby etc
馃憥 - Let's stick to code based service worker generation as it's more intuitive to write workbox code and we think that people will not have much difficulty writing service worker code by hand(P.S. we'll do our best to provide various examples).
I downvoted but as we discussed offline: a middle-ground here would seem to be really nice.
We scaffold (and therefore expose) a sw.js, but it's really just calling into code provided by the CLI and Workbox, glueing them together. The developer can replace this with their own logic should they wish to:
const manifest = preactCli.getPrecacheManifest();
const precacheOptions = preactCli.getPrecacheOptions();
preactCli.registerNavigationRoute();
workbox.precaching.precacheAndRoute(manifest, precacheOptions);
Right now most of the SW code we would be scaffolding is to deal with Brotli and ESM. We could abstract all of that away by prepending a preact-cli -specific "intro" into the SW code when bundling, so the user-visible code doesn't have to care about importing or invoking anything:
preact.registerNavigationRoute();
workbox.precaching.precacheAndRoute(
preact.manifest // <-- same as the current value of self.__precacheManifest
);
Here's what that would look like once built, with the preact-cli stuff prepended to the user code:
/*** preact-cli generated ServiceWorker setup ***/
importScripts(['workbox.js']);
self.preact = {
manifest: self.__precacheManifest,
registerNavigationRoute(fallbackUrl) {
// sets up NetworkFirst strategy with fallback to fallbackUrl (see my PR)
},
precacheOptions: { ... } // stuff for brotli
}
workbox.plugins.add(...) // for brotli
// here we monkey-patch Workbox in the one case where we can't presume to own options.
// To the user, this is just a normal workbox instance:
workbox.precaching.precacheAndRoute = (old => (manifest, options) => {
options = Object.assign({}, options || {}, preact.precacheOptions);
return old(manifest, options);
})(workbox.precaching.precacheAndRoute);
/*** User's sw.js code gets injected below ***/
preact.registerNavigationRoute();workbox.precaching.precacheAndRoute(preact.manifest);
This would also be nice during development, since the sw.js could be augmented with various checks ("did you register a navigation handler", etc) without any code modifications.
The injection approach is also useful because it will work with DefinePlugin.
Most helpful comment
I downvoted but as we discussed offline: a middle-ground here would seem to be really nice.
Option 1: move details into wrapper APIs
We scaffold (and therefore expose) a
sw.js, but it's really just calling into code provided by the CLI and Workbox, glueing them together. The developer can replace this with their own logic should they wish to:Option 2: Inject Smarts
Right now most of the SW code we would be scaffolding is to deal with Brotli and ESM. We could abstract all of that away by prepending a preact-cli -specific "intro" into the SW code when bundling, so the user-visible code doesn't have to care about importing or invoking anything:
Here's what that would look like once built, with the preact-cli stuff prepended to the user code:
This would also be nice during development, since the
sw.jscould be augmented with various checks ("did you register a navigation handler", etc) without any code modifications.The injection approach is also useful because it will work with
DefinePlugin.