12

I have a side project with Vue.js 3 and vite as my bundler.

After each build the bundled files got the same hash from the build before, like:

index.432c7f2f.js   <-- the hash will be identical after each new build
index.877e2b8d.css
vendor.67f46a28.js

so after each new build (with the same hash on the files) I had to reload the browser hard to clear the cache and see the changes I made.

I tried forcing a clearing with a different version number in the package.json, but:

  1. It does not work in the Vite/Rollup environment,
  2. it doesn't make sense to enter a new number by hand every time after a change.

Question:

Is there any way to configure vite to randomly create new hashes after a new build, or do you know another trick to clear the cache?

wittgenstein
  • 3,670
  • 7
  • 24
  • 41

2 Answers2

19

I found a solution how to add a random hash with each file with the build process witch will clear the cache in the browser:

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { hash } from './src/utils/functions.js'

export default defineConfig({
  plugins: [vue()],
  build: {
    rollupOptions: {
      output: {
        entryFileNames: `[name]` + hash + `.js`,
        chunkFileNames: `[name]` + hash + `.js`,
        assetFileNames: `[name]` + hash + `.[ext]`
      }
    }
  }
})
// functions.js
export const hash = Math.floor(Math.random() * 90000) + 10000;

output:

dist/index.html
dist/index87047.css
dist/index87047.js
dist/vendor87047.js

or

dist/index.html
dist/index61047.css
dist/index61047.js
dist/vendor61047.js

...
wittgenstein
  • 3,670
  • 7
  • 24
  • 41
  • That is great. It works for me. I could jsut refresh a page and get the the build content.but I do not get why. Vite seems to add already random numbers to its files? How is this different? – Ehrlich_Bachman Oct 12 '21 at 19:46
  • Yes, but it should be possible to see the new content without refreshing the page. The randomized hashing will do that for you. This way, every user (even those who have been on your site before) will see the latest content. – wittgenstein Oct 12 '21 at 21:43
  • Yes, I noticed and that was the reason I tried that in the first place, which is doing excactly that super gerat :D I am only confused, since Vite gives the files already an alpha numeric hash. Why did it not work straight away, but needs a forced numeric hash? – Ehrlich_Bachman Oct 13 '21 at 07:12
  • Here is the problem. The hash is not changed. **The browser cache thinks it is the old file**. With the randomized hash, the browser automatically fetches the new file and displays the site with all the new changes. Remember that not every user will update your page. That's what this randomized hashing will do for you. – wittgenstein Oct 13 '21 at 08:25
  • Thank you a lot for the explanation. That makes perfect sense. Just for clarification: That the hash var comes in from an import is just a preference or does it matters, if it is written direct in vite.config.js? – Ehrlich_Bachman Oct 13 '21 at 08:29
  • It does not matter. It's just javascript. I'm glad I could help. – wittgenstein Oct 13 '21 at 08:42
2

To go off of @wittgenstein answer, you can also just use the version from package.json as well (when you need to make sure cache is busted when releasing to production):

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { version } from './package.json'

export default defineConfig({
  plugins: [vue()],
  build: {
    rollupOptions: {
      output: {
          entryFileNames: `[name].js?v=${version}`,
          chunkFileNames: `[name].js?v=${version}`,
          assetFileNames: `[name].[ext]?v=${version}`
      }
    }
  }
})

And it doesn't have to be the filename itself, the browser will see any query arguments added to the file as a different file

A PWA may give issues with doing this, for that just add version to the filename similar to solution above:

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { version } from './package.json'

export default defineConfig({
  plugins: [vue()],
  build: {
    rollupOptions: {
      output: {
          entryFileNames: `[name].${version}.js`,
          chunkFileNames: `[name].${version}.js`,
          assetFileNames: `[name].${version}.[ext]`
      }
    }
  }
})
sMyles
  • 2,418
  • 1
  • 30
  • 44
  • how do you update the version number of your application? Because if you don't change them, the bundled files will have the same name and the client has to hard reload your page to see the changes. – wittgenstein Oct 12 '22 at 14:06
  • 1
    You update it in the `package.json` file assuming you are versioning your code that you're releasing (really for production releases) – sMyles Oct 12 '22 at 18:56