Solvedoffline plugin SWs & Webpack

Hey, question for the community here — this isn't an issue for offline-plugin but I'm asking here as y'all are the ones most likely it seems to have faced the same problem (and hopefully found some good solutions).

I've integrated offline-plugin into the next version of Gatsby and it works great. A problem I'm seeing though is that when I deploy a new version of a site, Webpack doesn't seem to maintain the same module ids for all modules. So after deploying, I load the site and the chunks that weren't changed are loaded from the service worker and the new chunks are loaded from the server but almost always there'll be a JS error when Webpack can't find a module id to call.

So perhaps I'm just doing this wrong — is the solution just to ensure that you load all chunks from the old SW until a new one is loaded and then switch over en masse?

16 Answers

✔️Accepted Answer

(text may have a lot of type because I wasn't re-reading/reviewing it)

I actually been thinking about this issue for a while. I'm not sure with which case exactly you have this problem (because there are few ways to get into it), but let me try to cover and answer all them. So..

There are couple of ways with offline-plugin to get into situation when old and new modules have conflicting module IDs, though, that's mostly related to webpack itself. So the solution on webpack level would be to use records, aka recordsPath option in webpack config. This option saves state between compilations and assigns permanent IDs to modules. Other solution on webpack level might be to use named modules (I don't remember exact name of plugin which does that).

Things in offline-plugin causing this problem:

  1. You are using updateStrategy: 'changed' (by default in v4 but not v3) which re-downloads only changed files based on hashed generated by webpack. The problem here is webpack doesn't always update chunk's hash when module IDs changed in it. Example: file added into chunk 2 caused module revalidation which changed IDs in chunks 1 and 2, but contents of the chunk 1 didn't change so new hash isn't generated.
    Solutions: 1) use recordsPath in webpack config, or 2) do not user updateStrategy: 'changed', or 3) generate file hashes on offline-plugin level instead of relying on webpack's generated hashes, this is already done for html-webpack-plugin because of how it works.

  2. You are using responseStrategy: 'network-first' (from v4) which may cause a situation where some chunks are loaded from the network and has new code and some other from the cache which has old code. The most right solution here is to not use responseStrategy: 'network-first' option or have all your assets unique named, e.g. with a hash in the name (which destroys the purpose of network-first though). recordsPath webpack option may help here, but I still assume there could be some conflicts between modules/chunks anyway.

  3. You are using caches.additional / caches.optional options in offline-plugin and aren't unique naming your assets. This is essentially the same problem as with responseStrategy: 'network-first', but in this case SW may cache new chunks along side with old ones which may cause such a problem.
    Solutions: 1) correctly name your assets (e.g. hash or version in its names), or 2) do not user caches.additional / caches.optional options. recordsPath has only potential fix effect as in previous section.

  4. You are applying ServiceWorker update once it's available but not reloading the pages. This causes pages to use new cache with the new code while they where used with the old one initially. So if you apply ServiceWorker update and then request some chunk from your server -- it will be loaded with the new code.
    Solutions: 1) Reload pages immediately after applying an update, or 2) Blocking all pages and telling the user to hit reload manually, or 3) do not apply an update immediately, but rather display an UI telling to the user that new update is really. If user wants -- apply update and reload the pages. 4) use recordsPath option which has approximately the same effect as in 2 and 3 sections.

@KyleAMathews I hope it helps. Please let me know if does or not and which exact case is yours here. Thanks! 👌

Related Issues:

offline plugin SWs & Webpack
(text may have a lot of type because I wasn't re-reading/reviewing it) I actually been thinking abou...
offline plugin How to exclude a specific path and all the paths underneath from being cached?
/admin and all the paths underneath are not part of my app so I want to avoid the SW from caching th...
flutter_cached_network_image using placeholder on CachedNetworkImageProvider or directly use CachedNetworkImage
@MahdiPishguy sorry for my late reaction ImageProviders can only return 1 image so this cannot retur...
flutter_cached_network_image Library is incompatible with latest Flutter master
I published a quick fix for this as 2.0.0-rc Wil remove the -rc tag when this flutter version reache...
haproxy Issue with checks after 2.0.6
As a workaround you can add option tcp-check or option httpchk in your listener/backend - checks wil...
axios Axios catch error returns javascript error not server response
I have exactly the same environment Try this: Modify from console.log(error) to console.log(
jest Bug: Watch mode on Linux causes a ENOSPC Node.js error
From my findings its not related to Jest at all On Linux (or Mac) we have a max number of system wat...
react RFClarification: why is setState asynchronous?
So here’s a few thoughts This is not a complete response by any means but maybe this is still more h...
react Preventing rerenders with React.memo and useContext hook.
This is working as designed There is a longer discussion about this in #14110 if you're curious ...
TypeScript Quick fix for 'unions can't be used in index signatures, use a mapped object type instead'
You can do this: Though Bar has no index signature (i.e. you can't then do (obj as Bar)[value as Foo...
webpack Cannot assign to read only property 'exports' of object '#<Object>' (mix require and export)
The code above is ok You can mix require and export You can't mix import and module.exports. ...
yarn Yarn Debian key expiry date updated (EXPKEYSIG 23E7166788B63E1E)
sudo apt-key adv --refresh-keys --keyserver also works to fix this issue for ma...
webpack How to exclude node_modules but one
@borm: a solution: Subj as example I create some module in another folder ( /projects/MY_MODULE ) MY...
yarn GPG error: stable InRelease NO_PUBKEY E074D16EB6FF4DE3
Doing curl -sS | sudo apt-key add - again was enough. ...
react React Fire: Modernizing React DOM
I love every of these points except the className change For latest status see an update from June 5...
angular Angular5.x lazyLoad problem, undefined is not a function
For others that find this issue via Google as i did: I had the same problem when trying to lazy load...
react starter kit How to call child component method from parent?
For example you can use Refs to Components approach like so: Demo:
react How should we set up apps for HMR now that Fast Refresh replaces react-hot-loader?
Okay here goes What Is Fast Refresh? It's a reimplementation of hot reloading with full support from...
svgo no such file or directory .svgo.yml
I noticed this problem with Yarn after someone had run yarn clean Deleting the .yarnclean file delet...
ant motion 模版代码下载下来导入到dva搭建的项目里面,启动时报错(npm start)
开启 JavaScript 就可以了 你好,我下载的Home项目引入到项目工程里面,为了方便,我全部放到了components下面,引入和基本流程没有问题。在家里的win10上面启动没有报错,在win...
react native gesture handler Unsupported top level event type "onGestureHandlerStateChange" dispatched
Because my navigators were created asynchronously the handler was registered too late and thus throw...
electron Requiring electron outside of main.js causes a TypeError
For anyone encountering this problem in the future and reading this thread Electron version: 1.3.5 O...
babel ReferenceError regeneratorRuntime is not defined
I had this issue using rollup with babel I just used this babel config to resolve it : ...
webpack nodejs 17: digital envelope routines::unsupported
workaround: Bug report What is the current behavior? Other relevant information: webpack version: 5....
meteor [] Error: ENFILE: file table overflow
I was getting the same after an upgrade to macOS Sierra Turns out macOS have a harsh limit on number...
webpack TypeError: Data must be a string or a buffer
Here is a workaround to help you to find the wrong import Using the latest 2.2.0 release although th...
vue router how to change document.title in vue-router?
Hi thanks for filling this issue You can simply define title in route's meta I really want set title...
babel eslint ESLint: 2.10.0 - Parsing error: Unexpected token =
parser: babel-eslint is OK! I'm using: and getting the following error: Parsing error: Unexpected to...
jest Error in Async Example: ReferenceError: regeneratorRuntime is not defined
This worked for me to fix ReferenceError: regeneratorRuntime is not defined in Jest: Then in .babelr...
jest babel-jest does not transpile import/export in node_modules when Babel 7 is used
For the record 🐛 Bug Report I started getting the dreaded SyntaxError: Unexpected token import erro...
react Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
You're exporting a React element not a component Change to Alternatively at the call site change <Co...
react Trigger simulated input value change for React 16 (after react-dom 15.6.0 updated)?
After some research of react source code I got a hack method for react 16: NOTICE: JUST A HACK ...
jest "Syntax Error: Invalid or unexpected token" with .png
I had the same error and resolved it by creating a assetsTransformer.js: Then add this to your jest ...
jest Watch mode stopped working on macOS Sierra
I had the same issue Upgrading watchman with brew install watchman to v4.7.0 fixed it. ...
material ui Module not found: Can't resolve 'material-ui-icons/Menu' Martial Next
For anyone else experiencing this issue: npm install @material-ui/icons
javascript How to configure React Native (Expo) project to use AirBnB's React rules via ESLint?
This is what I do in React and React Native: Step 1 Step 2 Backup your eslintrc file in case you wan...
yarn ERROR: There are no scenarios; must have at least one.
You've got the wrong yarn 😄 The Yarn you're executing comes from the cmdtest package: http://manpag...
webpacker localIdentName option moved in css-loader configuration
I faced same issue after upading css-loader but I solved it If you check css-loader readme ...
react native gesture handler Execution failed for task ':react-native-gesture-handler:compileDebugJavaWithJavac'
@zmGitHub npm i jetifier npx jetify fixed it for me on rn 0.6 I am fixing a incompatibility issue re...
atom Sometimes opening a file, Atom does not open in a new tab
This feature is called Pending Pane Items (formerly known as Preview Tabs) – this allows you to quic...
axios POST request works in Browser but not on Node
This might be considered a duplicate of #789 I was able to use the form-data package with Axios in n...
angular Cyclic dependency error with HttpInterceptor
I resolved simply not setting authService in constructor but getting in the intercept function. ...
lodash Find if array includes all elements from another array
You can do _.difference(subset superset).length === 0 to achieve this currently ...
fetch Error when POST file multipart/form-data
Setting the Content-Type header manually means it's missing the boundary parameter Remove that heade...
amplify js Uncaught ReferenceError: global is not defined in latest Angular 6 RC
Just for reference I have passed through this issue with adding these lines on my index.html head: ...
yarn Installation Problem: .yarn-metadata.json: Unexpected end of JSON input
I triggered this condition after a failed install of lodash.isfunction: If you trigger this you can ...
sequelize Class constructor Model cannot be invoked without 'new' and how getter v4 work?
Intypescript case my solution was to change target from es5 to es6 Hi all ...
yarn ERROR: [Errno 2] No such file or directory: 'add'
I was facing the same problem I am using Ubuntu (17.04) and used sudo apt install yarn to install ya...
react TypeError: func.apply is not a function / Uncaught TypeError: destroy is not a function
TypeError: destroy is not a function This is the real error and indicates that you're returning a va...
jest requestAnimationFrame warning with React 16
@mbifulco I managed to get this working for all test cases by loading a simple shim before each spec...