For Webpack hash, it is often used for CDN caching. What I understand is that if the file stays the same, the hash string that you pack will stay the same. Recently, I was asked about the difference between these three hashes, so I checked and found that they are very particular.
Let’s take a look at three hashes:
- [hash] is a “unique hash generated for every build”
- [chunkhash] is “based on each chunks’ content”
- [contenthash] is “generated for extracted content”
There are two code changes
The original code:
// file1.js
console.log('file1')
// file2.js
console.log('file2')
// file3.js
console.log('file3')
// index.js
require('./file2')
console.log('index')
// detail.js
require('./file1')
console.log('detail')
// webpack.config.js
const path = require('path')
const webpack = require('webpack')
module.exports = {
// mode: 'development',
// mode: 'production',
entry: {
index: './src/index.js'.detail: './src/detail.js',},output: {
filename: '[name].[hash].js'.path: path.resolve(__dirname, 'dist')}},Copy the code
First change:
// file2.js
console.log('file22')
Copy the code
Second change:
// index.js
require('./file2')
require('./file3')
console.log('index')
Copy the code
I’ll compare the three hashes in the order I understand them
hash
Each build generates a unique hash, and all file hash strings are the same. Source code build:
First change:
Did you see something you weren’t expecting? I just changed file2.js, the hash string of index.js has changed, but why has detail.js changed too? This is not a cache! No, upgrade!
chunkhash
The final hash of each file is determined by the chunk it imported
Source code build:
First change:
Second change:
The reason is module identifier, because the new module introduced by index has changed the ID value of all subsequent modules, so the module ID value introduced in the detail file has changed, and so has the chunkhash of the detail.
Don’t worry, WebPack already has a solution, which is to replace the default numeric ID naming convention with path naming. In Webpack 4, mode for Development is enabled by default, but the production environment is still the default ID. Webpack also provides a plugin to solve this problem
plugins: [
new webpack.HashedModuleIdsPlugin(),
],
Copy the code
After the plugin is added and you iterate through the code changes above, you will find that the hash string of the detail remains unchanged after the first and second changes, as expected.
In webpack, in the case of CSS, each entry file will be packaged with a JS file and A CSS file. In the case of chunkhash, the hash of JS and CSS files will be the same, which exposes a problem: You fixed a react bug, but did not change the style. After the update, the hash of the js and CSS files changed. This is still not good, CSS file hash string is not the best, then continue to upgrade!
contenthash
Contenthash generates a hash based on the extracted content.
The MiniCssExtractPlugin is used in the production environment to compress CSS. In this case, we specify the hash as contenthash in the plugin. You will find that after modifying the JS file, the HASH string of the JS file is changed, and the CSS hash string is unchanged. Perfect.
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].[contenthash:8].css'.chunkFilename: '[name].[contenthash:8].chunk.css'
})
Copy the code
If all hashes in the Webpack are set to contenthash, only CSS files can be modified. If js files are not modified, CSS files will change the hash string, and JS files will not change, so as to achieve the minimum update.
other
I looked up two popular scaffolds, create-React-app and UMI, and found that their entry files were configured with Contenthash
output: {
filename: '[name].[contenthash].js'.chunkFilename: 'cfn_[name].[contenthash].js',},Copy the code
Umi uses HashedModuleIdsPlugin for stable hash builds, but CRA does not. I see someone has already raised the issue: github.com/facebook/cr… Optimization. ModuleIds: “hashed” can also be used. Check the optimization
So the best practice is contenthash + HashedModuleIdsPlugin/optimization moduleIds: “hashed”
References:
- Stackoverflow.com/questions/3…
- Imweb. IO/topic / 5 b6f2…