webpack中hash和chunkhash是否是很眼熟?

前言

最近在研究webpack的东西,而后也陆陆续续整理了几篇文章,从里面能够学到许多有用的插件和node的一些模块,今天我要介绍的就是hash和chunkhash,这个在webpack打包的过程当中常常见到,有兴趣的能够关注一下个人github,点个star,关注和喜欢都行,🙏css

二者的使用

//使用hash的状况
output: {
  path: path.resolve(__dirname, '../dist/static'),
  publicPath: '/',
  filename: 'static/js/[name].[hash].js',
  chunkFilename: 'static/js/[id].[hash].js'
}
//使用chunkhash的状况
output: {
  path: config.prod.assetsRoot,
  filename: 'static/js/[name]-[chunkhash:16].js',
  chunkFilename: 'static/js/[id]-[chunkhash:16].js',
  publicPath: '/'
},复制代码

通常使用的时候,会用在文件的产出中,css和js都有,用于打包产出的文件html

hash和chunkhash是什么

你们都知道,用于优化页面性能的经常使用方法就是利用浏览器的缓存,文件的hash值,就至关于一个文件的身份证同样,很适用于前端静态资源的版本管理,前端实现增量更新的方案之一,那为何会有两个东西呢,咱们娓娓道来,先看二者的定义前端

  • hash

[hash] is replaced by the hash of the compilation.vue

compilation的hash值node

  • chunkhash

[chunkhash] is replaced by the hash of the chunk.webpack

chunk的hash值git

后者很容易理解,由于chunk在webpack中的含义就是模块,那么chunkhash根据定义来就是模块内容计算出来的hash值。
在理解前者以前咱们先来看一下compilation有什么做用github

compilation的浅析

webpack的官网文档中HOW TO WRITE A PLUGIN中对这个有一段文字的解析web

A compilation object represents a single build of versioned assets. While running Webpack development middleware, a new compilation will be created each time a file change is detected, thus generating a new set of compiled assets. A compilation surfaces information about the present state of module resources, compiled assets, changed files, and watched dependencies. The compilation also provides many callback points at which a plugin may choose to perform custom actions.浏览器

翻译:

compilation对象表明某个版本的资源对应的编译进程,当你跑webpack的development中间件,每当检测到一个文件被更新以后,一个新的comilation对象会被建立,从而引发新的一系列的资源编译。一个compilation含有关于模块资源的当前状态、被编译的资源,改变的文件和监听依赖的表面信息。compilation也提供不少回调方法,在一个插件可能选择执行制定操做的节点

而与compilation对应的还有一个compiler对象,咱们也来介绍一下,这样可以更方便理解compilation

The compiler object represents the fully configured Webpack environment. This object is built once upon starting Webpack, and is configured with all operational settings including options, loaders, and plugins. When applying a plugin to the Webpack environment, the plugin will receive a reference to this compiler. Use the compiler to access the main Webpack environment.

翻译:

compiler对象表明的是整个webpack的配置环境,这个对象只在webpack开始的时候构建一次,且全部的操做设置包括options,loaders,plugin都会被配置,当在webpack中应用插件时,这个插件会接受这个compiler对象的引用。经过webpack的主环境去使用这个compiler。

简单的说,compiler是针对webpack的,是不变的webpack环境,而compilation这个就是每次有一个文件更新,而后会从新生成一个,那么当你一个文件的更新,全部的hash字段都会发生变化,这就很坑了,原本咱们作增量更新就是想改的那个文件发生变化,可是若是所有都发生变化就没有意义了,咱们来看一下实际操做中的例子:

  • 修改前文件的hash

修改前文件的hash
修改前文件的hash

  • 修改后文件的hash

修改后文件的hash
修改后文件的hash

并且从上图中能够看出,每次有文件更新,会产生一个新的compilation,从而会用新的compilation来计算得出新的hash,并且每一个文件带有的hash值仍是同样的,这样的确定达不到咱们的要求,那么如何避免这个问题呢?——chunkhash

chunkhash

chunkhash是由chunk计算的得出的hash值,chunk指的是模块,这个hash值就是模块内容计算出来的hash值

  • 修改单个文件前的chunkhash

修改前的chunkhash
修改前的chunkhash

  • 修改后的文件的chunkhash

修改后的chunkhash
修改后的chunkhash

这里咱们还得提一个问题,好比像vue这些框架,把js和css共同放在一个里面会时,咱们通常会用一个插件叫extract-text-webpack-plugin,这样咱们就能把css单独打包,可是这样就会产生一个问题,这样打包出来的css的chunkhash和js的chunkhash会不会是同样的呢,其实我这么问了,固然是会的啦。咱们能够看一下下面两张图片。

chunkhash计算出的js
chunkhash计算出的js

chunkhash计算出的css
chunkhash计算出的css

其实也很简单,webpack的理念就是为了js的打包,style标签也会视为js的一部分,那么这咱们会发现,仍是有坑,当咱们只改css的时候,js也会同时发生改变,那么咱们仍是没有作到严格意义上的增量更新,那么咱们又该怎么解决呢?

contenthash

使用方式以下:

new ExtractTextPlugin({
  filename: 'static/css/[name]-[contenthash:16].css',
  allChunks: true
})复制代码

这样咱们看打包后的效果。

chunkhash计算出来的js
chunkhash计算出来的js

contenthash计算出来的css
contenthash计算出来的css

总结

静态资源的管理是前端很重要的一块,最近因为业务转型,本身也在尝试换个架子,那么确定得从研究webpack入手,如今webpack已是必不可少的工具之一,这篇博文有借鉴网上的,若有侵权删,可是研究得出的结论我会记忆一辈子,因此建议看完这篇的小伙伴本身动手配置一边,喜欢的能够去github上点个star,喜欢和关注都行,最近有点忙,可是我仍是天天会写一点博文。谢谢你们

相关文章
相关标签/搜索