How can i force a complete refresh (re downloading cached files) after each publish

Viewed 1465

I have a website built using ReactJS which is being continuously developed and i publish a new version and build almost every day, the people who use my website have this problem that even if they do a F5 and refresh the page, everything is Memory Cached for example the chunk files, which means they don't get the latest changes and they have to manually clear the browser cache to get some result!
So here is my question, how can i tell my app that "hey, this is a new build", so if a refresh F5 happens, it downloads everything and doesn't use the cached files
Any solution is much appreciated
Thanks.

Update 01: I just tried changing my jsconfig.json file, in hopes of changing the chunk name something like this:

{
    "compilerOptions": {
        "baseUrl": "src"
    },
    "include": [
        "src"
    ],
    "output": {        
        "chunkFilename": "[name].chunkv2.0.js"
    }       
}

But none of the chunks were different, meaning their name was a still [somehash].chunk.js
What am i doing wrong ?

2 Answers

Your best bet is to improve your build pipeline and ensure you are busting the browsers cache. Read Strategies for Cache-Busting, although this is aimed at CSS the principles apply for JavaScript too.

If you're using Webpack then checkout it's own documentation on the topic.

how can I tell my app that "hey, this is a new build"? so if a refresh F5 happens, it downloads everything and doesn't use the cached files

sure, you can

in hopes of changing the chunk name something like this main.bad98a53.chunk_v0.1.j

no need

How can you notify the changes to the website?

first, you should use [contenthash] fo chunk name in webpack, and when you publish a new version, the contenthash would change if the content of the chunk changed.

second, use the fetch to get the HTML text content which contains scripts and compare it with the previous one like string. The text would like this

"
<html>
  //...
  <script src="main.11bsfas21.js"></script>
</html>
"

// after publish
"
<html>
  //...
  <script src="main.aagssh.js"></script>
</html>
"

if it has a difference, execute location.reload(true)

the code would like this


let previous;
let htmlContent;

const diff = (callback) => {
  if (!previous) {
    previous = htmlContent;
    return
  }
  if (previous === htmlContent) return

  callback()
}

const loadContent = async () => {
  // get the html content
  const content = await window.fetch(location.host).then(res => res.text())
  return content
}

setTimeout(() => {
  loadContent()
     .then(content => {
       htmlContent = content;
       diff(() => location.reload(true))
     })
}, 1000)

this just an example, you can custom the callback like show a Model component. The main work compares the text of HTML, if the contenthash changes, the text of HTML wouldn't equal and invoke callback.

use location.reload(true), which would force the website to use the lastest source rather than use cache resources.

Related