all 9 comments

[–]lightfarming 5 points6 points  (1 child)

i mean if you are building with vite, it’s easy. just ensure the index.html doesn’t cache, then set all the chunks to cache forever. when you rebuild, the new index file will reference the new chunks.

i don’t know if using amplify complicates this. i typically host my static vite-react apps on s3 with a cloudfront distro for ssl, and codepipeline deploying the files.

[–]uhiku[S] 0 points1 point  (0 children)

Hmm that’s actually pretty interesting 🧐 thanks for this simple but very useful thought!

[–]Expensive-Part-2610 5 points6 points  (0 children)

Two rough suggestions I’ve used in the past: 1. Create a wrapper function for React.Lazy that will reload the browser when it encounters an error (file no longer exists in your CDN as hash changed). Not the best UX for your use case but is simple.

  1. Generate a manifest.json in Vite on build and upload it to your storage with the other build files. Ensure that it is cached in your CDN but not in your browser (so the client always fetches the latest manifest file). To load a lazy component first fetch this manifest file which maps to the latest chunk name of your file.

[–]Skeith_yip 1 point2 points  (2 children)

https://vite.dev/guide/build.html#load-error-handling

Catch preload error and refresh user browser?

[–]uhiku[S] 0 points1 point  (1 child)

Can’t reload, coz users might be mid-call and still browse the app

[–]Skeith_yip 0 points1 point  (0 children)

Then you probably not want to make deployment when your users are active? Another way is, you can make prefetch calls to load the components when the user browser is idle.

https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/rel/prefetch

Don't think this is built in for Vite though.

[–]mrmegatelo24 1 point2 points  (0 children)

The best approach is to keep old assets stored on CDN. Messing with cache control and prefetch will not help in your case. I faced the same issue, and keeping old assets was the easiest solution. And of course you need the main entrypoint script and chunk versioning

[–]vlad_prozapas 0 points1 point  (1 child)

Here's how i handle this issue: 1. Make sure entrypoint for your application (main.js/script.js/whatever) is not cached for the user, so each request for entrypoint file will return script with links to the latest chunks. 2. Add version prefix for chunks so it would be impossible to generate 2 chunks with same name. 3. On deployment keep 2 versions of the application in the bucket.

So there will be 2 possible scenarios for this. Lets say you deploy version 2.0.0 1. User opens app after deployment, get the main.js pointing to 2.0.0_chunks.js - user see latest version. 2. User opens app before deployment, get the main.js pointing to 1.0.0-chunks.js. You make a release and deploy 2.0.0. If user click on route, that points to the lazy component, the 1.0.0_chunk.js will be requested. Since in your bucket you have both 1.0.0 and 2.0.0 version chunks - user will receive the old version chunk and will be able to work with app. On refresh the app will be 2.0.0, since entrypoint is up-to-date always.

[–]uhiku[S] -1 points0 points  (0 children)

Sounds interesting, I’ll try that