webpack|webpack 学习笔记之十一 hash chunkhash contenthash
一.hash是什么?
hash 是一种散列算法.
它可以将[任意长度的二进制数]据映射成[较短的固定长度的]二进制值.
它的原理很简单,所有的数据,不管是图片,文字,视频,文件等乱七八糟的东西.
丢给一个固定的hash算法,只要文件的内容不发生改变,那么计算出来的hash永远都是一样的.
大家最熟悉的hash算法莫过于 MD5 了.
二.hash在前端开发的过程中,起到了哪些特别的作用?
前端开发,不管是用什么框架,什么打包工具,最终运行的环境是浏览器.
浏览器是有缓存机制的.如果一个文件的文件名不发生变化,那么浏览器就会有很大的可能去缓存这个文件(cache-control:no-cache除外.)
有时候,浏览器的缓存也是一把双刃剑.比如我们的某个css文件的内容实际上是改了,但是由于文件名没改.
浏览器就认为这个文件没有发生变动,不去再次发生请求从服务器获取,而是从本地缓存里读取.会导致用户看到的文件并不是最新的.
所以,经常会看到这样的css代码.
通过给一个基本没啥作用的查询字符串结尾,让浏览器认为这是一个动态的请求,从而获得最新的css文件的目的.
webpack
提供的类似的功能,就叫做hash功能.可以给打包出来的文件名,加上一串hash值,每次都可以生成一个新的文件名.
webpack 给文件名插入之 hash
webpack.config.js
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')module.exports = {
entry: {
indexName: path.join(__dirname, 'index.js'),
appFileName: path.join(__dirname, 'app.js')
},
output: {
path: path.join(__dirname, 'dist'),
filename: '[name]_[hash].js'
},
mode: 'development',
plugins: [
new CleanWebpackPlugin()
]
}
打包查看结果:
文章图片
image.png 查看打包的输出结果
- 整个项目的hash值是:
e4b33a6c56df04dda9be
-
appFileName
的hash值是:e4b33a6c56df04dda9be
-
indexName
的hash值是:e4b33a6c56df04dda9be
index.js
文件.// index.js
let i = 0
重新打包
文章图片
image.png
- 整个项目的hash值:
414410450aa6ab446bc3
-
appFileName
的hash值是:414410450aa6ab446bc3
-
indexName
的hash值是:414410450aa6ab446bc3
hash是项目级别的.只要项目内部改动了任意一个位置,所有设置了
hash
的文件的hash
值都会跟着一起发生改变.(那些从来压根没改过的文件的hash也会跟着改变).这样的话,完全就不合理了.没变内容的文件如果hash也变了,文件
名就变了.文件变了,浏览器就需要重新下载这个文件,达不到缓存的作用了.
webpack 给文件插入之 chunkhash
chunkhash是针对entry的每一个入口文件,独立的hash。如果entry里面的其中一个文件内容改变,只会改变这个入口
文件build之后的文件名,而不会影响到其他文件。
webpack.config.js
const path = require('path')
// import { CleanWebpackPlugin } from 'clean-webpack-plugin' // node.js 还不支持ES6的import模块导入语法.
const {
CleanWebpackPlugin
} = require('clean-webpack-plugin')module.exports = {
entry: {
indexName: path.join(__dirname, 'index.js'),
appFileName: path.join(__dirname, 'app.js')
},
output: {
path: path.join(__dirname, 'dist'),
// filename: '[name]_[hash].js'
filename: '[name]_[chunkhash].js'
},
mode: 'development',
module: {
rules: [{
test: /\.(png|jpg|gif)$/,
use: [{
loader: 'file-loader',
options: {
name: '[name]_[contenthash].[ext]'
}
}]
}]
},
plugins: [
new CleanWebpackPlugin()
]
}
查看结果
文章图片
image.png
- 整个项目的 hash 值是:
9ec8f05fbffa71101b9c
- appFileName 的 hash 值是:
420fbddeda08d6b1d3c0.
- indexName 的 hash 值是:
bdd32b0728173915f845
现在修改 app.js
let i = 0
查看结果:
文章图片
image.png
- 由于对于整个项目而言,的确有文件的内容被修改了,所以 hash 值从原来的
9ec8f05fbffa71101b9c
变成了2bd51d157cc397ec1523
. 在情理和意料之中. - appFileName 的 hash 值 :
49d983a60c15f9a92cb4
而原来的是420fbddeda08d6b1d3c0
. 也在情理和意料之中,因为我们修改了app.js
的代码let i = 0
- indexName 的 hash 仍然是原来的
bdd32b0728173915f845
, 没有改动过代码,所以还是原来的值.
contenthash 顾名思义, 就是根据当前文件的内容,来计算hash值.
将非output的文件名设置hash或者chunkhash,比如(css,image等)都将无效,而且默认使用的是contenthash
比如:
rules: [{
test: /\.(png|jpg|gif)$/,
use: [{
loader: 'file-loader',
options: {
name: '[name]_[hash].[ext]' // 按道理是当前项目的hash值.
}
}]
}]
结果:
文章图片
image.png 按道理来说,设置了hash,图片文件名应该和项目的hash一致.
但结果,它俩完全不一样,肉眼都可以一眼看出,起码长度都不一样.
webpack.config.js
rules: [{
test: /\.(png|jpg|gif)$/,
use: [{
loader: 'file-loader',
options: {
// name: '[name]_[hash].[ext]' // 按道理是当前项目的hash值.
name: '[name]_[chunkhash].[ext]' //Path variable [chunkhash] not implemented in this context: 282-8_[chunkhash].jpg
}
}]
}]
配置费output文件成为chunkhash,直接报错.
//Path variable [chunkhash] not implemented in this context: 282-8_[chunkhash].jpg
压根就没实现这个hash的功能.
配置contenthash
rules: [{
test: /\.(png|jpg|gif)$/,
use: [{
loader: 'file-loader',
options: {
// name: '[name]_[hash].[ext]' // 按道理是当前项目的hash值.
// name: '[name]_[chunkhash].[ext]' //Path variable [chunkhash] not implemented in this context: 282-8_[chunkhash].jpg
name: '[name]_[contenthash].[ext]' // 根据文件的内容,生成的hash
}
}]
}]
结果:
文章图片
image.png 发现和配置
hash
的情况一致.也就是说,给jpg等静态资源配置hash
默认就会转成contenthash
.总结:
- hash [范围最大] 是针对整个项目的,如果把整个项目当做是一个文件(为什么非要是单个的1.txt就这么好理解成是文件了?),那么这个项目文件的内容发生改变(文件删除添加,文件内容修改),都会导致整个项目的hash值发生改变.
- chunkhash [范围其次] 是根据当前入口文件最终打包出来的js文件.output. 当前依赖链中,有任意文件变动,都会改变这个hash值.
- 而contenthash [范围最小] 就仅仅只是针对当前文件的内容.
hash,chunkhash,contenthash,说白了,就是根据不同的范围,给最终生成的文件名里加一串字符串.(hash把整个项目当成一个文件; chunkhash把一个独立的entry个output当前一个文件(多个模块之间的依赖当成一个chunk); contenthash则是把单个文件当成是一个文件)
它们有一个共同的特点就是,最终它们都会是生成一个独立的文件,且在浏览器中,会有一个链接指向它们.
有链接指向它们,它们就能利用所谓的各种hash,来做缓存了.
一张图解:
文章图片
image.png 【webpack|webpack 学习笔记之十一 hash chunkhash contenthash】码云
推荐阅读
- 课程理论知识学习|矩阵论理论知识(二)
- 课程理论知识学习|随机过程理论知识(四)
- 课程理论知识学习|矩阵论理论知识(1)
- 基于Spring|基于Spring Boot和Spring Cloud实现微服务架构学习(一)-Spring框架介绍
- 数学建模|数学建模之python(一)
- 笔记|初步认识机器学习(Machine Leaning)
- 学习|Python3学习
- 笔记|15天完成民猫电商毕设——消息模块收尾(12th day)
- 笔记篇|通信原理学习笔记(一)(通信系统基本概念和组成)
- Linux学习之路|Linux——SSH服务篇与防火墙简单配置