关于webpack的hash

1.为什么使用hash
当不使用hash的时候,每次打包后生成的文件名都是一样的,浏览器可能缓存上一次的结果而无法加载最新数据

  1. webpack有那些 hash

参考官网webpack支持多种hash

关于webpack的hash_第1张图片
image.png

image.png

[hash]模块标识符的hash

当没有任何改动来执行打包命令的时候,文件的hash还是改变了, 查看官方给出的解释是:

关于webpack的hash_第2张图片
image.png

boilerplate(boilerplate 指 webpack 运行时的引导代码)、runtime 和 manifest(运行webpack配置文件生成的包含所有引用的第三方包内引入的模块文件,并为他们赋予了唯一的数字id)
对此, 我们可以将boilerplate抽离出来
关于webpack的hash_第3张图片
image.png

得到抽离出的runtime
关于webpack的hash_第4张图片
image.png

[chunkhash]是chunk内容的hash

关于webpack的hash_第5张图片
chunkhash.png
关于webpack的hash_第6张图片
chunkhash.png
关于webpack的hash_第7张图片
hash.png
关于webpack的hash_第8张图片
hash.png

在上面的截图中中我们看到hash生成的文件[hash]部分完全相同,而[chunkhash]则不同, 这里就需要我们来理解chunkhash 是每一个js的模块对应的值是不同的(根据js里的不同内容进行生成)。

当然 这里也存在的问题是,当新增一个模块,其他模块的[chunkhash]也随之改变,其根本原因还是 module identifier,因为新引入的模块改变了以后所有模块的 id 值。

解决方案是将默认的数字 id 命名规则换成路径的方式。

关于webpack的hash_第9张图片
image.png
NamedModulePlugin和HashedModuleIdsPlugin

当然如果是生产环境的话,全路径是有点太长,这两个plugin让webpack不再使用数字给我们的模块进行命名,这样每个模块都会有一个独有的名字,也就不会出现增删模块导致模块id变化引起最终的hash变化了。
使用HashedModuleIdsPlugin 插件来根据路径生成的 hash 作为 module identifier。

plugins: [
    new webpack.HashedModuleIdsPlugin(),
],

NamedModulePlugin一般用在开发时,能让我们看到模块的名字,可读性更高,但是性能相对较差。HashedModuleIdsPlugin更建议在正式环境中使用。

ExtractTextPlugin

打包时发现,js和js引入的css的 chunkhash 是相同的,导致无法区分css和js的更新。
原因是webpack的编译理念,webpack将css视为js的一部分,所以在计算chunkhash时,会把所有的js代码和css代码混合在一起计算。
解决方法css是使用 ExtractTextPlugin 插件引入的,这时候可以使用到这个插件提供的 contenthash ,如下(使用后css就有独立于js外的指纹了),

//提取css文件
new ExtractTextPlugin({
     filename:'css/[name].[chunkhash:8].css'  //提取chunkhash8位码
})

[contenthash]

在使用ExtractTextWebpackPlugin时生效,代表内容hash。

现在如果只改变 CSS 文件,会发现对应的 entry JS 和 CSS 文件的 chunkhash 都会改变。(只能对抽离的 CSS 文件使用 contenthash)。我们需要应该是改变了什么就反应到什么文件上。而不是 CSS 和 JS 文件的 chunkhash 同时改变或不变,无法区分 CSS 和 JS 的更新。

所以这里抽离出来的 CSS 文件将使用 contenthash,以区分 CSS 文件和 JS 文件的更新。

为了一份理想的缓存文件,我们需要做这些事情:
* 抽离 boilerplate([runtime & manifest)
* 将 module identifier 默认的数字标识方式转成使用路径标识
* JS 文件使用 chunkhash
* 抽离的 CSS 样式文件使用 contenthash
* gif|png|jpe?g|eot|woff|ttf|svg|pdf 等使用 hash
* 设置 namedChunks 为 true

你可能感兴趣的:(关于webpack的hash)