Good addition to refresh SWs for Meteor users, offering a more updated option for SWs.
This is my take on Service Workers based on my experience. I always used a custom approach to handle Service Workers, like the one you’ve provided in the repo, to keep full control, well, mainly because the options weren’t so many for Meteor back then. But over time, as projects required more tweaks and advanced features, the SW file became harder to follow and maintain.
That, among other reasons, led me to delegate this part to more modern, maintained, and reliable solutions like workbox
. These are used by many devs globally. The challenge is, integrating them with Meteor.js takes extra effort, while other bundlers provide this out of the box with plugins, fully maintained by a broader open community.
That’s why I started experimenting with modern bundlers alongside Meteor.js. My next focus was to offload repetitive tasks to better tools and open us up to more options.
With Workbox, in my case used via Webpack (but also available for Vite and others), I just configure the SW strategy I want. Here’s a code snippet from my app config of SWs:
const swConfig: WebpackPluginInstance = new GenerateSW({
swDest: 'sw.js',
include: ['/manifest-en.json', '/manifest-es.json'],
exclude: [/main\.html$/, /.*lingui_loader.*/],
excludeChunks: ['main'],
skipWaiting: true,
clientsClaim: true,
inlineWorkboxRuntime: true,
cleanupOutdatedCaches: true,
runtimeCaching: [
{
urlPattern: ({ url }) => ['/healthcheck'].includes(url.pathname),
handler: 'NetworkOnly',
},
{
urlPattern: ({ request }) => request.mode === 'navigate',
handler: 'NetworkFirst',
options: {
cacheName: 'pages',
matchOptions: { ignoreVary: true },
},
},
{
urlPattern: ({ request }) =>
request.destination === 'style' ||
request.destination === 'script' ||
request.destination === 'worker',
handler: 'StaleWhileRevalidate',
options: {
cacheName: 'assets',
cacheableResponse: {
statuses: [200],
},
matchOptions: { ignoreVary: true },
},
},
{
urlPattern: /\.(?:png|jpg|jpeg|svg|gif)$/,
handler: 'CacheFirst',
options: {
expiration: { maxEntries: 30 },
cacheName: 'images',
matchOptions: { ignoreVary: true },
},
},
{
urlPattern: /\.md$/,
handler: 'CacheFirst',
options: {
expiration: { maxEntries: 15 },
cacheName: 'documents',
matchOptions: { ignoreVary: true },
},
},
],
});
With this setup, the sw.js
is generated automatically and served in public
folder, by describing the different strategies for offline support, cache resolution and other features. You can even generate it using a modern bundler and then just copy it into Meteor.js. But with modern bundlers, I don’t need to switch context or move files, everything stays in sync and easier to manage. I still get full control, but in a cleaner and more readable way than writing all logic manually and move files around.
Of course, each method has its pros and cons. Not sure if this is useful for others, but I’d like to support having this kind of flexibility as an option for Meteor users. Hopefully, with upcoming work on modern bundler integration, I can show more of it.
PD: We could build a Meteor plugin that hooks into the bundler lifecycle to integrate Workbox, but I’ve preferred to delegate that to a modern bundler with plugin support and active maintenance, which also unlocks other benefits from bundlers more easily.