持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情
背景
前端页面防止浏览器缓存,解决方案之一就是,给文件后面添加一串随机的字符串或者数字,我之前的一种做法是给后面添加t=new Date().getTime();
现在webpack里面的出口文件也就是bundle文件也可以使用这种去解决浏览器缓存。
在webpack中,我们想要使用hash的方式去解决浏览器缓存的问题,我们只要出口文件名里面设置hash就行了,这种就叫做指纹策略。
这种是Webpack自带的,不用手动再去安转插件库什么的。
一共有三种方式:
- hash
- chunkhask
- contenthash 它们的侧重点各不相同,往下看就知道了。
hash
文件名里面会加入一串随机字符,每个bundle文件是同步的,并且每个bundle文件的hash也是一样的。
先看一下之前的配置以及效果:
之前的webpack.config.js:
构建后的效果:
出口文件是没有hash处理的。
现webpack.config.js这样配置的:
出口文件配置的文件名那里加了hash的处理,
[name]-[hash].js,意思是原来入口文件名字后面拼接一个 - + 一串随机的字符 。 里面的hash位置文件名的任何地方都是可以的,看自己喜好。
其他文件代码:
src/index.js:
import {add} from './other.js'
import css from "./index.css";
import test from "./test.less";
console.log("hello 浅唱");
src/other.js:
export function add(a,b){
return a+b
}
src/list.js:
console.log('我是list文件呀');
src/index.css:
body {
background: red;
}
src/test.less:
body{
div{
height:200px;
background:url('./images/01.jpg') 0 0 no-repeat;
}
}
项目目录:
看效果:
出口文件的index.js和list.js文件名都有了随机的字符串,并且每次代码更新时,构建后,出口文件的hash是变化的,否则不变。
我文件里面随便改一下,看看:
改之后的src/index.js:
import {add} from './other.js'
import css from "./index.css";
import test from "./test.less";
console.log("hello 是浅唱");
改之前的src/index.js:
import {add} from './other.js'
import css from "./index.css";
import test from "./test.less";
console.log("hello 浅唱");
执行构建后:
出口文件中的
index.js和list.js文件名中的hash是改变了。
但是,大家有没有觉得hash字符实在太长了,没关系,可以配置,如下:
-[hash:6]意思是最长hash为6位。
但是有个问题,我只改了index.js的内容,list.js并没有改变,但是出口文件,list.js是跟着index.js一块改变的,也就是说其中一个bundle文件改变了,其他的bundley也会跟着一块改变,虽然他们属于不同bundle,如何解决呢,chunkhash。
chunkhash
影响的是改变的那个chunks,而不是所有bundle是同步的,每个bundle文件的hash也就是那串字符串也是不一样的。
看看如何配置:
webpack.config.js:
执行构建成功后:
可看到,出口文件index.js和list.js的hash不一样了,我们再改一下入口文件src/index.js试一下:
改之前:
改之后:
执行构建后,出口文件:
我们看到改变的只是chundle文件index.js,list.js并没有改变。
但是我们改一下src/index.js: 看下dist里面css的变化
改之前:
import {add} from './other.js'
import css from "./index.css";
import test from "./test.less";
console.log("hello 浅唱");
改之后:
import {add} from './other.js'
import css from "./index.css";
import test from "./test.less";
console.log("hello 是浅唱");
webpack.config.js里配置一下css,给css也加一个hash方便判断。
先这样把css配置一下在插件里面配置:给css一个配置了一个文件名和css输出的位置。
效果是这样的:
加上chunkhash后:
效果:
但是它和出口文件index.css的hash是一样的,所以猜想,它的改变会影响index.css,因为src/index.css是被src/index.js引入的,index.css是一个chunk一个代码片段,而入口文件src/index.js也是一个chunk也是一个代码片段,所以出口文件dist/index.js,bundle文件也是一个chunks,它里面有三个chunk分别是index.js和index.css,list.js。所以说index.js和index.css是属于同一个chunks,chunkhash这样设置,也是会同一个chunks里面的chunk是互相影响的。
回过头来校验一下:
上面的index.js改变之后:
代码改之前的构建效果:
改之后:
index.css是随着index.js变化的,事实上我们不需要index.css变化,你js自己变了,就改自己的呗,我index.css为什么要跟着你变化,我多累呀。有解决方法吗?
有的,contenthash来啦
contenthash
顾名思义,自身内容更新,自己才会更新。
配置一下:
webpack.config.js:
给css添加了这个contenthash,意思是只有css改变了,出口文件中的css才会改变,否则不改变,我们改一下src/index.js试试看:
改之前:
import {add} from './other.js'
import css from "./index.css";
import test from "./test.less";
console.log("hello 浅唱");
改之后:
import {add} from './other.js'
import css from "./index.css";
import test from "./test.less";
console.log("hello 是浅唱");
看效果:
看:index.js的改变,并没有影响到index.css,它两的hash也不一样。
但是注意,因为css设置了contenthash,但是index.js它设置的还是chunkhash,所以,index.js改变不会影响到css,但是css的改变还是会影响到index.js的。
总结
指纹策略可以解决前端的浏览器缓存问题,文件名都会加一串随机的字符串,分别有3种方式,他们的侧重点不同,chunk之间chunks之间的影响度不同:
- hash:缺点是改变其中一个bandlu文件,全部的bandlu都会跟着一块改变,它们之间是同步的。并且每个bundle文件的hash也就是那串字符串是一样的。
- chunkhask:影响的是改变的那个chunks,各自的chunks之间不是同步的,每个chunks也就是bundle文件的hash也就是那串随机字符是不一样的。
- contenthash:自身内容更新,才会更新 多页面用chunkhash,单页面用hash,其他资料用contenthash