webpack中的hash、chunkhash和contenthash

这三个hash值都是webpack在打包的时候根据内部算法生成的一串字符串,总的来说最大的不同就是其囊括控制的范围大小不同,对应的控制颗粒度不同。

hash

hash是对webpack整个一次构建而言,在webpack构建中,文件都会带上对应的MD5值,构建生成的文件hash值都是一样的。如果出口是hash,那么一旦针对项目中任何一个文件的修改,都会构建整个项目,重新获取hash值。如果有目的性的缓存就会失败。

chunkhash

chunkhash的范围可以针对某个模块而言,它会从入口出发,对依赖文件进行解析,构建对应的chunk和hash值。一般的使用是在生产环境对公共库和程序入口文件单独抽离开,单独打包构建,用chunkhash的方式对这些打包后的文件带上相应hash值。在线上,只要公共库和入口没变,其hash值就不会改变,从而达到缓存的目的。

eg:

entry:{
    main: path.join(__dirname,'./main.js'),
    vendor: ['vue']
},
output:{
    path:path.join(__dirname,'./dist'),
    publicPath: '/dist/',
    filname: 'bundle.[chunkhash].js'
}

此时入口有两个,main和vendor,此时的打包就会生成main和ventor两个hash值,这两个hash值是分别以main和vendor为入口出发根据依赖文件构建生成的chunk和hash值。(chunk可以理解为入口+他依赖的文件构成的模块)
在这里插入图片描述

contenthash

contenthash的范围更具体和更小,即对某一个文件而言,在webpack中的用法一般是分离js和css,单对css文件来设置。因为上面的chunkhash存在一个问题:

chunkhash以入口和依赖文件构建的chunk模块,只要对应其中一个css或则js改变,与其关联的文件hash值也会改变,但其他内容并没有改变,一定意义上的缓存也就失效。
比如我js文件逻辑改变了,但是我css样式并没有改动,css文件就应该从缓存中加载,不应该从服务器中重新获取,浪费带宽和性能。

所以在项目中,通常做法是把项目中css都抽离出对应的css文件来加以引用。

比如使用mini-css-extract-plugin:

const miniCssExtractPlugin=require("mini-css-extract-plugin");

module.exports={
    module:{
        rules:[
            {
                test: /\.css$/,
                use:[
                    miniCssExtractPlugin.loader,
                    'css-loader'
                ]
            }
        ]
    },
    plugins:[
        new miniExtractPlugin({
            filename: 'main.[contenthash:7].css'
        })
    }
}

在这里插入图片描述
main模块用了chunkhash,这里单独把main的css抽离出来用contenhash处理,打包后即使css文件所处的模块里就算其他文件内容改变,只要css文件内容不变,那么就不会重复构建。

posted @ 2019-12-03 18:16  Lawliet__zmz  阅读(498)  评论(0编辑  收藏  举报