Webpack 三种文件指纹策略 js、css、图片字体资源的指纹设置
文件指纹
是什么?
文件指纹就是打包输出后文件名的后缀
有什么用?
文件指纹通常可以用来做一些版本管理,在发布的时候,有修改的文件就发布上去,没有修改的文件还可以继续用浏览器本地缓存,这样可以加速页面访问
文件指纹类型以及如何生成
文件指纹有三种类型
- Hash
- Chunkhash
- Contenthash
Hash
和整个项目的构建有关,只要项目文件有修改,整个项目构建的hash就会修改
Compiler 和 Compilation
Compiler: webpack启动的那一次创建的对象
Compilation: 只要有一个文件发生了变化,Compilation就会发生改变。 hash受到Compilation的影响而改变
ChunkHash
ChunkHash和webpack打包的chunk有关,不同的entry入口会生成不同的chunkhash值,使得chunk保持独立
如果a页面变化,那么b页面也会变化,这其实是没必要的,因此需要chunkhash
chunkhash只能用于生产环境,在热更新的时候不会生成
Contenthash
根据文件内容定义hash指纹,文件内容不变,则contentHash不变
如果修改了js,css没有变,如果css也采用chunkhash,导致css内容没有变化但是上传的css chunkhash发生了变化
因此对于css内容,一般都是根据文件内容来生成css指纹
配置指纹
将webpack.config.js拆分为两份
webpack.dev.config
webpack.prod.config
对于生产环境的配置应该去掉热更新相关插件,同时将mode改为production
同时将package.json中的build脚本指定为webpack.prod.config
"build":"webpack --config webpack.prod.js"
"dev":"webpack-dev-server --config webpack.dev.js --open"
设置js文件指纹
直接在output下修改chunkhash
仅当entry入口文件内容有变化时,打包生成的chunkhash值才会变化
配置之前输出:
app.js
react-comp.js
配置之后输出:
app_76762735.js
reactComp_456cec63.js
module.exports = {
output:{
path:path.join(__dirname,'./dist'),
filename:'[name]_[chunkhash:8].js'
}
}
完整版
'use strict';
const path = require('path');
module.exports = {
// 生产模式还是开发模式
mode: 'production',
// 入口 指定入口文件
entry: {
app:'./src/index.js',
// search:'./src/search.js',
reactComp: './src/react-comp.js'
},
// 出口
output: {
// 指定输出目录
path: path.join(__dirname, 'dist'),
filename: '[name]_[chunkhash:8].js'
},
// 配置loader
module: {
rules: [
{
test: /.js$/,
use: 'babel-loader'
},
{
test:/.css$/,
use:[
'style-loader', // 再将样式插入到style标签中
'css-loader' // 将css转换成commonjs
]
},
{
test: /.less$/,
use: [
'style-loader', // 再将样式插入到style标签中
'css-loader', // 将css转换成commonjs
'less-loader' // 将less文件转换成css文件
]
},
{
test: /\.(png|jpg|gif|jpeg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 40 * 1024 // 40k
}
}
]
},
{
test: /\.(woff|woff2|eot|ttf|otf|otf)$/,
use: [
'file-loader'
]
}
]
}
}
设置图片字体等文件指纹
设置file-loader或url-loader的name,使用[hash]
此处的hash和前面提到的js hash不一样,这里指的也是文件内容的hash,默认采用md5生成
如果转换成base64则无法查看hash效果,因此先将url-loader改成file-loader,然后给图片设置文件指纹
module.exports = {
module:{
rules:[
{
test:/\.(png|svg|jpg|gif)$/,
use:[
loader:'file-loader',
options:{
name:'/img/[name]-[hash:8].[ext]'
}
]
}
]
}
}
占位符名称
[ext] 资源后缀名
[name] 名称
[path] 相对路径
[folder] 文件所在的文件夹
[contenthash] 文件内容hash,默认由md5生成
[hash] 文件内容hash,默认由md5生成
[emoji] 一个随机指代文件内容的emoji
完整版配置
'use strict';
const path = require('path');
module.exports = {
// 生产模式还是开发模式
mode: 'production',
// 入口 指定入口文件
entry: {
app: './src/index.js',
reactComp: './src/react-comp.js'
},
// 出口
output: {
// 指定输出目录
path: path.join(__dirname, 'dist'),
filename: '[name]_[chunkhash:8].js'
},
// 配置loader
module: {
rules: [
{
test: /.js$/,
use: 'babel-loader'
},
{
test: /.css$/,
use: [
'style-loader', // 再将样式插入到style标签中
'css-loader' // 将css转换成commonjs
]
},
{
test: /.less$/,
use: [
'style-loader', // 再将样式插入到style标签中
'css-loader', // 将css转换成commonjs
'less-loader' // 将less文件转换成css文件
]
},
{
test: /\.(png|jpg|gif|jpeg)$/,
use: [
{
loader:'file-loader',
// 图片指纹
options:{
name:'[name]_[hash:8].[ext]'
}
}
]
},
{
test: /\.(woff|woff2|eot|ttf|otf|otf)$/,
use: [
{
loader:'file-loader',
options:{
name:'[name]_[hash:8].[ext]'
}
}
]
}
]
}
}
设置css文件指纹
避免css没变js变化的时候,css的chunkhash值也随着打包一起变化,因此css应该使用contenthash,
目前css是以style标签存在于页面中,因此需要使用MiniCssExtractPlugin来抽取成文件再设置文件指纹
因此这个插件和style-loader是互斥的
npm i mini-css-Extract-plugin@0.6.0 -D
配置webpack
除了配置插件外,还需要把插件的loader加进去, 并且这个插件和style-loader是互斥的,因此需要将style-loader替换成MiniCssExtractPlugin.loader
module.exports = {
loader:{
rules:[
{
test:/\.css$/,
use:[
MiniCssExtractPlugin.loader,
'css-loader',
]
},
{
test:/\.less$/,
use:[
MiniCssExtractPlugin.loader,
'css-loader',
'less-loader'
]
}
]
}
plugins:[
new MiniCssExtractPlugin({
filename:'[name]_[contenthash:8].css'
})
]
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
2019-09-24 7 JavaScript函数调用&this关键字&全局对象&函数调用&闭包
2019-09-24 6 JavaScript函数&内置构造&函数提升&函数对象&箭头函数&函数参数&参数的值传递与对象传递
2019-09-24 5 JSON&与JavaScript转换&JavaScript:void(0)&JavaScript代码规范