Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the purpose of webpack [hash] and [chunkhash]?

Could somebody tell me what is the the purpose [hash] and [chunkhash] and where do they come from?

output: {     path: "/home/proj/cdn/assets/[hash]",     publicPath: "http://cdn.example.com/assets/[hash]/" }  
like image 560
Stepan Suvorov Avatar asked Feb 03 '16 12:02

Stepan Suvorov


People also ask

What hash does webpack use?

js for webpack output config will change each chunk across each build. In order to change hash of only that chunk for which there is corrosponding change in webpack entry, you need to use “chunkhash” instead of “hash”. In short you have to replace name. [hash].

How does webpack Contenthash work?

Webpack provides a method of templating the filenames using bracketed strings called substitutions. The [contenthash] substitution will add a unique hash based on the content of an asset.


1 Answers

This one wasn't obvious for me for a while, so I think it deserves some more detailed explanation.

What the official documentation says:

A brief description from the official documentation about their purpose:

A simple way to ensure the browser picks up changed files is by using output.filename substitutions. The [hash] substitution can be used to include a build-specific hash in the filename, however it's even better to use the [contenthash] substitution which is the hash of the content of a file, which is different for each asset.

Another explanation one by one from the documentation of output.filename:

  • [hash] is a "unique hash generated for every build"
  • [chunkhash] is "based on each chunks' content"
  • [contenthash] is "generated for extracted content"

Let's make it more more understandable with examples:

I have 3 files in my src directory: index.js, index.css, vendors.js

Relevant parts from my example Webpack config:
(not a full, working config!)

entry: {   index: ["./src/index.js", "./src/index.css"],   vendors: ["./src/vendors.js"] }, output: {   filename: "[name].[hash].js" } plugins: [   new MiniCssExtractPlugin({     filename: "[name].[hash].css"   }) ] 

So I have 2 chunks name, index and vendors, but look that the index chunk will also have css content because it imports a css file in the array. When building, the css part will be exported to a separate file using MiniCssExtractPlugin (in my case) but Webpack knows that index.js and index.css belong to the same chunk.

Now let's try to build it with different hashing types. (changing the two filename option equally)

Using [hash]:

enter image description here

Every file has the same hash, because [hash] is generated based on all of our used source files. If I re-run the build without changing anything, the generated hash will remain the same. If I edit only one file then hash will change and all my generated bundles will have this new hash in their name.

Using [chunkhash]:

enter image description here

As you see, the 1st and 2nd files were coming from the same index chunk, so they have the same hash in their name. It's because [chunkhash] is generated based on the whole content of the given chunk. So if I edit let's say index.css and re-build, the files coming from the index chunk will have a new hash, but the one from vendors chunk will remain the same as was before.

Using [contenthash]:

enter image description here

This one is obvious. Each generated file has got a unique hash in their name, calculated from the content of that file. If I change let's say index.css an re-build, only the generated index.css will have a new hash.

like image 107
szegheo Avatar answered Oct 06 '22 09:10

szegheo