The gotchas of caching ES-modules

Going all modern/native with an offline PWA using javascript modules, I had some problems getting the serviceworker cache to work as intended with es6 modules.

For my future self or anybody else googling around I thought I would write up on my findings quickly.

To use native modules the main-file must be loaded from a script-tag with a type=”module” attribute on it. But it turns out that script[type=module] makes a different kind of request to the server (specifically the mode+credentials parts).

Two different requests for the same file

This means that when we try to match that request against the cache, with cache.match(event.request), it won’t match the cache-entry for the file added using the normal request-type or the string-based approach cache.addAll([‘app.js’, ‘module1.js’, …]).

The solution should be to manually match the request-type when adding the the cache. Big shoutout to @jeffposnick for pointing me towards this 🤘

But it turns out this doesn’t work perfectly either. So I actually ended manually creating the request-object in the fetch-listener to match the cache… this works, but doesn’t seem very pretty, and hopefully will go away as this matures!

Obviously this is pseudo-code, and you should come up with a better approach for when to actually create the request objects yourself, and you probably want to fallback to the network as well… (and other things)