Preface:

Webpack has become the most popular packaging tool at present, and as it gets more and more attention, we pay more and more attention to its performance optimization, how to optimize compilation speed, reduce packaging volume… This article will cover the three hashes that webPack generates when compiled

Hash — compiled to produce

When instantiated, WebPack creates a Tapable subclass Compiler globally that holds initial configuration information, runs compile entry functions, registers and calls plug-ins, and so on.

Every time you compile, you instantiate a compilation object. That object is responsible for loading files, closing them, optimizing them, chunking them, hashing them, reconstructing them, and so on, from the start to the end of the compilation, and the compilation creates the hash. This means that a new hash value is created for each compilation, and the hash for all files is the same because it was generated by the same compilation

First build:

Modify the app. Js

Second build:

We can see that all the files have changed, the disadvantages:

  1. This causes all files to be recompiled once
  2. Unable to take advantage of the browser cache policy because the file was regenerated

Chunkhash — Build chunk generation

First of all, what is chunk?

As we know, each import file is a chunk, and each chunk is composed of the import file and its dependencies. Asynchronously loaded files are also regarded as a chunk, and chunkhash is compiled by the module every time. According to the modules and their dependent modules, chunk is constituted to generate the corresponding chunkhash, which indicates that the chunkhash value of each chunk is different, that is, each chunk is independent and does not affect each other, and the update of each chunk will not affect the compilation and construction of other chunks

First build

Change the entry file for a second build

However, each chunk is composed of CSS and JS, meaning that when one of the files changes, the chunk is recompiled and the contenthash is generated.

contenthash

Different hashes are generated for the content of the file. The hash will be generated only when the content of the file changes. In this case, the mini-CSs-extract-plugin needs to be used to extract the CSS file of each chunk, separate the CSS from the JS file, and then modify the CSS

Pay attention to the point

  1. The output JS must also end in contenthash. In the case of chunkhash, since CSS has changed, the whole chunk will still generate a new hash at compile time, even if the packaged JS contenthas not changed
  2. If the entry file does not rely on asynchronous chunks, the entry file output by contenthash will not be recompiled. If the entry file output by contenthash does depend on asynchronous chunks, the entry file will be recompiled regardless of the hash output because the CSS contenthash has changed. The CSS file specified by the link tag inserted asynchronously also changes, representing the contents of the entry file, so whatever hash is recompiled, but the asynchronous chunk does not change

webpack.config.js

    const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    const HTMLWebpackPlugin = require('html-webpack-plugin')
    
    module.exports = {
      mode: 'development'.entry: {
        main: './index.js'
      },
      output: {
        filename: 'js/[name].[chunkhash].js'.chunkFilename: 'js/[name].[contenthash].js'.publicPath: '/'
      },
      module: {
        rules: [{test: /\.css$/.use: [{
              loader: MiniCssExtractPlugin.loader,
              options: {
                outputPath: 'css/'}},"css-loader"]]}},plugins: [
        new HTMLWebpackPlugin({
          template: 'index.html'.filename: 'index.html',}).new MiniCssExtractPlugin({
          // Options similar to the same options in webpackOptions.output
          // both options are optional
          filename: "css/[name].[contenthash].css".chunkFilename: "css/[name].[contenthash].css"}})],Copy the code

index.js

    const asyncChunk = () => import('./asyncChunk')
    console.log(asyncChunk, 1);
    
    document.onclick = () => asyncChunk()
Copy the code

asyncChunk.js

    import './common.css'

    export default 'asyncChunk'
Copy the code

First build

Change the CSS file for a second build

conclusion

Contenthash makes more sense for caching