🤢
History
sw-toolbox & sw-precache
Main Issues of sw-*
- Confusion how they worked together
- sw-toolbox had a precache method
- sw-toolbox's code was delicate
- sw-precache was all or nothing
- sw-precache was popular at the cost of flexibility
- sw-precache did some *funky* lookup logic for precaching
Goals
- Merge sw-precache's logic into a library
- Put sw-precache and sw-toolbox under one roof
- Break apart sw-toolbox into smaller modules so pieces can be used (or not used) based on user needs
- Improve testing infra to allow future changes and growth
General Approach Taken v1
- Source would be in ES Module syntax
- Hopes of developers using Workbox this way
- Hopes tree-shaking would be affective
- Provide builds that can be used in the browser
- Provide a low level and high level API
- Merged
- Testing was improved
- New features (over toolbox)
- BG Sync
- Broadcast Cache Update
- Simplified pre-caching logic
v1/v2
v1/v2
- One Module Ruled
- workbox-sw
- Size was a big criticism (48KB)
- Documentation was a mess
- Webpack wasn't really webpack
- Developer experience was still messy outside of the sw-precache style build step
v1 (Issues)
v1 (Issues)
// Where does this come from? Bare in mind version string.
importScripts('/workbox-sw.dev.v2.0.3.js');
const workboxSW = new WorkboxSW({
// Options here can affect any module
clientsClaim: true,
});
// `precache()` is defined on `workbox-sw` instead of
// on the `workbox-precaching` module
workboxSW.precache([{
url: 'precached.txt',
revision: '43011922c2aef5ed5ee3731b11d3c2cb',
}]);
workboxSW.router.registerRoute(
'https://httpbin.org/image/(.*)',
workboxSW.strategies.cacheFirst({
// Theses options require specific plugins to exist in current context
cacheName: 'images',
cacheExpiration: {
maxEntries: 2,
maxAgeSeconds: 7 * 24 * 60 * 60,
},
cacheableResponse: {statuses: [0, 200]},
})
);
v1 (Issues)
v3 (Beta)
workbox
.
.
<module>
*
v3 (Beta)
workbox
.
.
<module>
*
workbox-sw module
lightweight proxy object
[A convenience/loader]
v3 (Beta)
workbox
.
.
<module>
*
workbox-*
precaching
backgroundSync
etc
v3 (Beta)
workbox
.
.
<module>
*
- workbox <proxies> the module namespace
- If module needs loading:
importScripts('<cdn or path>/<module name>.<dev or prod>.js') - Return the module namespace
- If module needs loading:
v3 (Beta)
workbox
.
.
<module>
*
importScripts('<CDN or Path>/workbox-sw.js');
workbox.precaching.*
via workbox-sw:
new Proxy(this, {
get(target, key) {
if (target[key]) {
return target[key];
}
const moduleName = MODULE_KEY_TO_NAME_MAPPING[key];
if (moduleName) {
target.loadModule(moduleName);
}
return target[key];
},
});
v3 (Beta)
workbox
.
.
<module>
*
without workbox-sw:
importScripts('<CDN or Path>/workbox-core.<dev or prod>.js');
importScripts('<CDN or Path>/workbox-precaching.<dev or prod>.js');
workbox.precaching.* <- Namespace from workbox-precaching
v3 (Beta)
- Works with and without workbox-sw
- The magic can be removed
- We can switch between dev and prod easily
- Localhost vs prod by default when loaded via workbox-sw
- Forces clean module split
- Config options
- Access via Global namespace
v3 (Beta)
Browser Builds
importScripts('<CDN or Path>/workbox-sw.js');
workbox.precaching.*;
import precaching from 'workbox-precaching';
precaching.*;
ES Module
v3 (Beta)
import precaching from 'workbox-precaching';
precaching.*;
Source Code is ES Modules
{
..
"main": "build/workbox-precaching.prod.js",
"module": "index.mjs",
..
}
Main and Module in package.json
v3 (Beta)
Browser Builds are Enforced Rules + Rollup
- All workbox modules are treated as external
- Default for Node, but easy to skip with monorepo
- External modules MUST reference a specific file and export (Helps tree shake)
- Rollup treats external modules as "globals" and swaps reference for `workbox.<module>`
// The implementation of workbox-foo
import {logger} from 'workbox-core/_private/logger.mjs';
export default function() {
logger.log('hello');
}
this.workbox = this.workbox || {};
this.workbox.foo = (function(logger_1) {
return function() {
logger_1.log('hello');
};
})(workbox.core._private.logger)
v3 (Beta)
Input -> Output
v3 (Beta)
Import / Export Consistency
- Every module must have a default export
- Enables same API for ES Modules and browser
- Importing from a workbox-* module must be either a `public` or `private` export
- A simple rule to enforce and validate with tests
- A simple rule to ensure between ES Modules and browser builds
v3 (Beta)
CLI
(NPM) build
webpack
v3 (Beta)
webpack
Â
Using the correct events and supporting chunks
Â
More community PR's since improving
v3 (Beta)
Inject Manifest
Â
Find `precacheAndRoute([])` and inject a list of files and revisions.
OR
Inject `importScripts('precache-1234.js')` which exposes `self.__precacheManifest`.
Â
Good for people wanting their own SW, but not intuitive.
v3 (Beta)
Generate SW
Â
Same as sw-precache with option of use CDN or local Workbox builds
Â
Hard to get away from this once you've started.
Configuration is growing and duplication Config -> Templated Code.
v3 (Beta)
- Modules are seperate (No single module)
- Size is 22.7KB vs 48KB
- This assumes using everything
- Documentation is cleaner
- Webpack is cleaner
- Developer experience will hopefully improve*
*Maybe I made things worse
v3 (Beta)
v3 (Beta)
// Version is directory name, can be CDN or local
importScripts('<CDN or Local>/<version>/workbox-sw.js');
// Options in respective places
workbox.clientsClaim();
workbox.core.setLogLevel(workbox.core.LOG_LEVEL.debug);
// All methods under module namespace
workboxSW.precaching.precacheAndRoute([{
url: 'precached.txt',
revision: '43011922c2aef5ed5ee3731b11d3c2cb',
}]);
workboxSW.router.registerRoute(
'https://httpbin.org/image/(.*)',
workboxSW.strategies.cacheFirst({
cacheName: 'images',
// Plugins are explicit
plugins: [
workbox.cacheExpiration.plugin({
maxEntries: 2,
maxAgeSeconds: 7 * 24 * 60 * 60,
}),
workbox.cacheableResponse.plugin({
statuses: [0, 200],
}),
],
})
);
Downsides of Workbox
- Still rough edges around API
- Small set of maintainers / committee
- Docs
- SW are still hard
- Build is pretty crazy
Workbox V3 Deck
By gauntface
Workbox V3 Deck
- 1,290