DEV Community

Cover image for Clear Cache on build for React Apps.

Clear Cache on build for React Apps.

Ammar Tinwala on July 16, 2020

What problem are we trying to solve? Every time a build is created and deployed, the user has to do a hard refresh of the webpage to cle...
Collapse
 
eddiemonge profile image
Eddie Monge Jr

I don't understand the point of this article. This is done automatically already. The build system outputs the built files using a hash. The index.html uses those to load it. When you push new code up, the index.html is replaced with updated references. Set the index.html to never be cached and add the new build files alongside the old ones and people going to the site initially get the new version and people already on the page will continue to work and then when they refresh they get the new version as well.

Collapse
 
arturogallegos profile image
Arturo Gallegos

When your project requires to implement strict security policies in some cases it is necessary to disable hashes, for this reason we need another option to clear all caches.

however I agree that this method could be shorter, in my opinion only need attach in the serviceWorker.js a console.log with current date

Collapse
 
ammartinwala52 profile image
Ammar Tinwala

Hi Arturo

I'm extremely sorry for such a late reply. Can you help me out how I can make this code shorter ?

Thread Thread
 
arturogallegos profile image
Arturo Gallegos

Of course, as I commented only need attach a console log in your service worker, for example:

Create a file updateBuildTime.js

const fs = require('fs');

const sw_file = './src/forceUpdateCache.js';

const buildDate = `console.log(${new Date().getTime()})`

fs.writeFile(sw_file, buildDate, "utf8", (error) => {
  if(error){
    return console.warn(error);
  }
  return console.warn('All right')
});
Enter fullscreen mode Exit fullscreen mode

then update your package file with

"scripts": {
   ....
    "build": "node ./updateBuildTime.js && node scripts/build.js && cat src/forceUpdateCache.js >> build/service-worker.js",
    ....
  },
Enter fullscreen mode Exit fullscreen mode

With these lines you can add a console.log, I have used the current date to ensure a new value is different to the last version, but you can use another value

The reason of this is very simple, own service worker update all cache our app but need at least one change to download the new version of this file, the console.log with a date is perfect, it will be diferent in each build.

Thread Thread
 
ammartinwala52 profile image
Ammar Tinwala

Thanks Arturo, I will check this out.

Collapse
 
ammartinwala52 profile image
Ammar Tinwala

Hi Eddie

I'm very sorry for such a late reply. The point of this article was, whenever I was generating the build, I was getting the same hash files through create-react-app. It seems to have changed now. I'm getting different has files generation during the build.
Can you share me some example on how to "Set the index.html to never be cached" only on new builds ? It will help us all

Collapse
 
jukim1234 profile image
jwkim

Awesome! Finally, I've found this solution. I wonder how every SaaS company could manage to work without this solution. I'm very curious why there has been no simple solution for this important problem in the React eco-system.

Collapse
 
pragziet profile image
Pragz

Hi Ammar great article, I need you help here, I tried Dinesh approach, but my app is indefinitely reloading, pls guide here, happy to share more info.

Collapse
 
ammartinwala52 profile image
Ammar Tinwala

Hi Pragz, can you create a small poc with issue share it me via github. I will have a look at it and get back to you.

Collapse
 
pragziet profile image
Pragz • Edited

One thing to check is that my app is not build using create-react-app, so do not have any Service worker at all and hence not being registered, still the below code will be able to work, also my app uses react-router.

    if (caches) {          
      caches.keys().then(async function(names) {
        await Promise.all(names.map(name => caches.delete(name)))
        })
    }

    // delete browser cache and hard reload
    window.location.reload()
Enter fullscreen mode Exit fullscreen mode

Also is it possible to share your email / twitter , for further 1-1 discussion, thanks for the support.

Thread Thread
 
ammartinwala52 profile image
Ammar Tinwala

@Pragz : Please email me at ammartinwala52@gmail.com. We can connect over there

Thread Thread
 
ammartinwala52 profile image
Ammar Tinwala

I ran the above code and it is working perfectly fine at my end.

Thread Thread
 
pragziet profile image
Pragz

Sent the referral mail!

Collapse
 
amanchaudhary1998 profile image
AmanChaudhary1998

I am also facing the same issue as it goes under the infinite loop please guide me how fix this issue
window.location.reload()

Collapse
 
ammartinwala52 profile image
Ammar Tinwala

Hi Aman

I'm extremely sorry for such a late reply. If you are still facing the issue, please email to me your code at ammartinwala52@gmail.com

Collapse
 
vishalvishalgupta profile image
vishalvishalgupta

Can you please check once again your implementation? The react web app gets reload only because of withClearCache's useEffect. The code is never going in refreshCacheAndReload. And also, if intentionally, I wanna get the code fall in refreshCacheAndReload function, It lets the UI into never ending rerendering. Please check your implementation and revert me back.
FYI, your buildDate in package.json and meta.json are always going to be same and if they are going to be same, then if (momLatestDateTime.isAfter(momCurrentDateTime)) {
is always going to give you false.

Collapse
 
ammartinwala52 profile image
Ammar Tinwala

Hi Vishal

I'm very sorry for such a late reply. Can you check the answer to Khorengrig that I just mentioned. It explained what exactly happens.

If you are still not clear then please email me ammartinwala52@gmail.com

Collapse
 
alexisyepes profile image
Alexis Yepes Sanabria

Thanks again for this article. I implemented this approach, but the first time my page loads, I can still see the old version. After closing the tab and reopening it I can see the new version. Is this what is suppose to be happening?

Collapse
 
alexisyepes profile image
Alexis Yepes Sanabria

Never mind! That happened the first time after the first change. Then every time a change something I can see the most recent version live!!! Thanks a million sir

Collapse
 
ammartinwala52 profile image
Ammar Tinwala

Hi Alexis

I'm very sorry for such a late reply. I'm glad that I could be of help. Keep writing. Cheers.

Collapse
 
davidcastillo4 profile image
DavidCastillo4

Hi Ammar, Thank you so much for the post. I'm trying to get it to work for me but I'm getting the errors in the pic I provided. Can you please help me if you don't mind. Thanks again for the post!!!

Collapse
 
khorengrig profile image
khorengrig

Who can explain me what is going in this file. update-build.js. Every time you run build command your package.json buildDate and meta.json buildDate will be the same(You are inserting the same value). Which way this code will work?

Collapse
 
ammartinwala52 profile image
Ammar Tinwala

Hi Khorengrig

Im very sorry for this very very late reply.
Both dates are generated at the same time, and when you generate your build and deploy, at that point of time the api call from meta.json will fetch the latest build date and it will be compared with package.json date. If package.json date is cached it will be a mismatch and then only the refresh will happen. If your server/deployment configuration is such that it always takes the latest build then your package.json buildDate and meta.json buildDate will always be the same.
I hope you got the point.

Collapse
 
briang123 profile image
Brian Gaines

Looks like there is a react-cache-buster npm package that is basically the same as this. It can be found here: npmjs.com/package/react-cache-buster.

Collapse
 
ammartinwala52 profile image
Ammar Tinwala

Hi Brian

I'm very very sorry for such a late reply. Thanks for sharing I will check that out.

Collapse
 
jasimur profile image
Jasim Uddin

It's calling API without login. How I can solve this problem

Collapse
 
ammartinwala52 profile image
Ammar Tinwala

Hi Jasim

I'm very very sorry for late reply. You would have to place some kind of authentication check first if you want to call the api. If auth is successful then load the ClearCache component which in turns call the API.

Collapse
 
alexisyepes profile image
Alexis Yepes Sanabria

How would you integrate the ClearCache component if App.js is a class Based component? Thanks in advance

Collapse
 
ammartinwala52 profile image
Ammar Tinwala

Hi Alexis, you can refer to the App.js code and CacheBuster code in this article by Dinesh
dev.to/flexdinesh/cache-busting-a-...

Here the implementation is class-based component. Let me know if you have any queries.