45

I created an app with vue-cli and then I build the dist folder for production.

The app is deployed on IIS with flask backend and works fine.

The problem occurs when I have to make some changes and I have to redo the deployment. After this, users call me because app doesn't work but if I clear the chrome cache, the app works fine again.

How can I fix this problem? Is there a method to clear chrome cache automatically when I release a new application version?

Thanks

my dist folder

enter image description here

deployment: copy and paste folder dist on IIS

if files in dist folder are correct, maybe the problem is in axios cache? i have make some changes also to rest apis

nickb84
  • 591
  • 2
  • 6
  • 11

10 Answers10

42

I had the same problem and changing (incrementing) the version number in package.json before running the build command fixed it.

For example by default the version number is set to "0.1.0"

package.json file:

{
  "name": "project-name",
  "version": "0.1.1",
  "private": true,
  ...
}
Delphin RUKUNDO
  • 553
  • 5
  • 8
  • 4
    This is better way for force cache update. – Ish Jun 10 '21 at 20:48
  • after run npm run build only change on package json there is no need to commit into git , did u know why ? its really integrate to command `npm run build` ? i have already push my dist from version `0.1.1` then change into `1.1.1` then run npm run build, but there is no need to commit or push . i think we need to `npm install first`, right ??? – Yogi Arif Widodo Aug 25 '22 at 21:38
28

If you use vue-cli, then it has built-in webpack configs for building dist. And in fact it adds hash-names to output files. But if it was removed somehow, you can add it back to webpack config like

  output: {
    filename: '[name].[hash].bundle.js'
  }

And your app will looks like this: enter image description here

And even more, you do not need to handle how all this stuff will be added to html, coz webpack will figure it out for you.

bonusrk
  • 669
  • 5
  • 12
  • 5
    Your solution seems to work. Created 'vue.config.js' with module.exports = { configureWebpack: { output: { filename: '[name].[hash].bundle.js' } } } Vue CLI does seem to have hashing enabled, by default: https://cli.vuejs.org/config/#filenamehashing – akauppi Jun 09 '20 at 09:16
  • 2
    This only changes the name of my app.bundle.js but not the other files like /js/0.js – Stefan Höltker Oct 21 '20 at 15:01
  • because chunk names settings placed in other param of webpack settings, depending of what solution(plugin) you use to split chunks – bonusrk Oct 21 '20 at 20:31
  • This works somewhat for me. The only thing is it doesn't update the hash every time. How can we update the hash each time you run build? – waseber Mar 17 '23 at 16:11
  • well, it has different hash-build strategies, which you define with names inside the square bracers. so for example you can change [hash] to [contenthash] and it will build hash-name based on context, and rebuild on any changes in a content. (but of course the hashes will be same for the same content) – bonusrk Mar 24 '23 at 08:15
3

You need to add a version query to your js file. This is how a browser can know if the file has changed and needs to download the new version.

So something like:

<script src="main.js?v=1.1"></script>
<script src="main.js?v=1.2"></script>

etc...

T. Short
  • 3,481
  • 14
  • 30
  • but where? in index.html? – nickb84 Jan 08 '20 at 14:53
  • Yes in the html page that loads your script. Usually webpack adds this version tag automatically. You could try adding it yourself. If you can't, then share your config with us so we can see what is going on. – T. Short Jan 08 '20 at 14:58
2

Assuming this is nothing to do with service worker/PWA, the solution could be implemented by returning the front-end version.

axiosConfig.js

axios.interceptors.response.use(
  (resp) => {
    let fe_version = resp.headers['fe-version'] || 'default'
    if(fe_version !== localStorage.getItem('fe-version') && resp.config.method == 'get'){
      localStorage.setItem('fe-version', fe_version)
      window.location.reload() // For new version, simply reload on any get
    }
    return Promise.resolve(resp)
  },
)

You can also ensure the fe-version is returned based on any sort of uniqueness, here I have used the commit SHA.

Full Article here: https://blog.francium.tech/vue-js-cache-not-getting-cleared-in-production-on-deploy-656fcc5a85fe

bragboy
  • 34,892
  • 30
  • 114
  • 171
1

You can't access the browser's cache, that would be huge a security flaw.

To fix it, you must send some headers with your flask responses telling the browser not to cache you app.

This is an example for express.js for you to get the idea:

  setHeaders: function (res, path, stat) {
    res.set('Cache-Control', 'no-cache, no-store, must-revalidate') // HTTP 1.1
    res.set('Pragma', 'no-cache') // HTTP 1.0
    res.set('Expires', '0') // Proxies
  }

You can read a lot more about caching in here.

rodurico
  • 751
  • 7
  • 17
1

This is an older post, but since I could not find the solution for this problem online, ill just post this here in case someone else might find it usefull.

I added the hash to the appllication chunk files via the webpack.mix.js file by adding:

mix.webpackConfig({
    output: {
        chunkFilename: 'js/[name].js?id=[chunkhash]',
    },
})

This adds a fingerprint to the actual chunks and not just the app.js file. You can add a version name to the app.js file aswell by adding version(['public/js/app.js']); at the end of the file, or add filename: '[name].js?[hash]' to the output block.

My complete webpack.mix.js:

const mix = require('laravel-mix');

mix.webpackConfig({
output: {
    chunkFilename: 'js/main/[name].js?id=[chunkhash]',
  }
}).js('resources/js/app.js', 'public/js').vue()
    .postCss('resources/css/app.css', 'public/css', [
    //
]).version(['public/js/app.js']);

In my laravel blade file I used

<script src="{{ mix('js/app.js') }}"></script> 

to load the app.js file with the correct version fingerprint.

0

The answer for me was caching at my DNS provider level. Basically, I'm using Cloudflare DNS proxy and they are caching the website so in development mode I was not getting the code updates. I had to clear the cache many times to get anything to change. I had to wait a significant period of time before anything update.

Turned it off and it stopped doing that.

Pat M
  • 41
  • 3
0

the method I want to suggest

<script src="{{ asset('js/app.js?time=') }}{{ time() }}" defer></script>

Akbarali
  • 688
  • 7
  • 16
0

add below script in publc/index.html

<head>
...
  <script type="text/javascript" language="javascript">
    var timestamp = (new Date()).getTime();
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = "<%= BASE_URL %>sample.js?t=" + timestamp;
    document.head.appendChild(script);
  </script>
...
</head>
anson
  • 1,436
  • 14
  • 16
-9

could you try ?

vm.$forceUpdate();

Also it's possible that the component it self needs a unique key :

<my-component :key="unique" />
Mostafa Abdellaoui
  • 355
  • 1
  • 6
  • 15