Let me try to phrase the current issue:
**Caching issue**
Whenever we deploy a new version of `index.bundle.js`, an outdated version of `index.bundle.js` is still loaded by many clients for a period of time.
There is varnish cache (on the server) and browser cache (on the client).
**Varnish cache**
We now have 2 files cached in varnish:
- `index.html`
- `index.bundle.js`
Varnish caches these files **independently**, for a configured period of time (= **3600s**).
**Solution**
To prevent out-of-sync files, we can either:
# rename the JS file to a hashed named. `index.bundle.js` becomes `index.{hash}.js`
# append a query parameter to the JS file. `index.bundle.js` becomes `index.bundle.js?rev={hash}`
So that the HTML knows exactly what revision it wants to load.
**Problem with both options:**
- During deployment the `assets` folder needs to be synced before `index.html`
-- otherwise for X milliseconds, the html points to a JS file that does not exist on the server yet and varnish will cache the 404 for 5 minutes.
--- this means the page will behave like if the user had JavaScript disabled for 5 minutes.
**Problem with option 1:**
- We will generate a new file for each change. So we need to remove old files after some X period of time.
-- Kinda hard to automate.
- If we clean the folder on each build/deployment,
-- until varnish caches the new html file, varnish will keep returning the cached old JS file for a bit (even if it got removed on the server), and once it's expired varnish will return a 404 (for 5 minutes) thus giving people a page without JS.
--- @jgirault: As a user, I would hate to suddenly get a poor JS-free user experience for no apparent reason.
**Problem with option 2:**
- If `index.bundle.js` in varnish expires before `index.html`, then the server/varnish will return the cached **old** html file AND the **new** version of the JS file (even though it has the right old revision appended)
-- it is only a problem if the new JS file only works for the new html file and breaks with the old one.
-- it is only a problem when you change both the JS + the HTML file and the new JS does not provide backward compatibility.
**Compromise possible:**
- We go with option 2 (appending `?rev={hash}` ), and when we know the JS has no backward compatibility with the old html (change in the DOM structure), we rename the new file to `newindex.bundle.js` and maintain the old `index.bundle.js` on the server for some time.
-- The old version needs to stay online more than varnish expiration time.
-- No automation possible, deciding to rename the file and doing it must be manual.
--- Our build script can have a config object `{previous_production_file_name: 'index.bundle.js', new_production_file_name: 'newindex.bundle.js'}` to automatically preserve the old file, generate the new file, and clean the folder of any other file.
---- (if we don't want to be this creative, we can also use a number `{previous_production_file_number: 1, new_production_file_number: 2}` will do `bundle-1.js` and `bundle-2.js`)
/cc @MaxSem & @ebernhardson to review and correct me if I am writing non-sense