Tip:304 仍然会发送请求,通常请求头中 If-Modified-Since 的值和响应头中 Last-Modified 的值是相同的。
If-Modified-Since: Sat, 17 Jul 2021 02:34:06 GMT Last-Modified: Sat, 17 Jul 2021 02:34:06 GMT接下来我给静态资源增加缓存,这里就增加一个 10 秒的缓存:
// server.js - app.use(express.static('dist')); + app.use(express.static('dist', { maxAge: 1000 * 10 }));再次请求,发现 main.js 首先是 304,接下来10秒内状态码则是200,大小则指示来自内存,时间也变为 0 ms。过10秒后再次请求,又是 304。
现在有一个问题,在强缓存期间,如果出现了bug,我们哪怕修复了,用户使用却还是缓存中有问题的代码。
我们模拟一下这个过程图:先将缓存改长一点,比如 1 天,用户访问先输出 1,让浏览器缓存后,我们再修改代码让其输出 2,用户再次访问会输出什么?
// server.js app.use(express.static('dist', { maxAge: '1d' })); // index.js console.log('1');重新打包生成 dist,接着用户通过浏览器访问,控制台输出 1。
修改 js,重新打包生成 dist,再次访问,控制台还是输入 1。
// index.js console.log('2');注:不要强刷,因为用户不知道强刷,也不会去管。
于是我们打算从文件名入手来解决此问题,我们依次来看看 hash、chunkhash和conenthash。
hash核心代码如下:
// index.js import './a.css' console.log('1'); // a.css p{color:red;} // webpack.config.js module.exports = { output: { filename: 'main.[hash:10].js', }, plugins: [ new MiniCssExtractPlugin({ filename: "[name].[hash:10].css", }) ] }重新打包:
> npm run build > webpack-example3@1.0.0 build > webpack Hash: b2e057d598ca9092abd3 Version: webpack 4.46.0 Time: 4837ms Built at: 2021-07-14 8:17:54 ├F10: PM┤ Asset Size Chunks Chunk Names index.html 417 bytes [emitted] main.b2e057d598.css 12 bytes main [emitted] [immutable] main main.b2e057d598.js 5.22 KiB main [emitted] [immutable] main Entrypoint main = main.b2e057d598.css main.b2e057d598.js main.b2e057d598.js.map主要看生成的 css 和 js 文件,名字中都带有相同的值 b2e057d598,取的是生成的 Hash 的前10位。index.html 中也会自动引入对应的文件名。
现在浏览器访问,文字是红色,控制台输出1。
接着模拟修复缺陷,将文字改为蓝色,再次打包。
p{color:blue;} > npm run build > webpack-example3@1.0.0 build > webpack Hash: ed2cd907a36536276d20 Version: webpack 4.46.0 Time: 4771ms Built at: 2021-07-14 8:29:14 ├F10: PM┤ Asset Size Chunks Chunk Names index.html 417 bytes [emitted] main.ed2cd907a3.css 13 bytes main [emitted] [immutable] main main.ed2cd907a3.js 5.22 KiB main [emitted] [immutable] main浏览器访问,文字确实变为蓝色。但 js 和 css 都重新请求了,再看打包生成的文件,js 和 css 也都重新生成了新的文件名。这个会导致一个问题,只修改一个文件,其他的所有缓存都会失效。
Tip:这里修复的是 css,如果修复 js 也同样会导致所有缓存失效。
chunkhashhash 会导致所有缓存失效,我们将其改为 chunkhash,还是存在相同的问题。请看示例:
将 hash 改为 chunkhash:
// webpack.config.js module.exports = { output: { filename: 'main.[chunkhash:10].js', }, plugins: [ new MiniCssExtractPlugin({ filename: "[name].[chunkhash:10].css", }) ] }修改 css,然后重新打包,发现 js 和 css 文件也都重新生成了,虽然 chunkhash 与 hash 值不相同,但 main.js 和 main.css 中的 chunkhash 是一样的:
> npm run build > webpack-example3@1.0.0 build > webpack Hash: 8c1c035175aae3d36fea Version: webpack 4.46.0 Time: 5000ms Built at: 2021-07-14 9:16:46 ├F10: PM┤ Asset Size Chunks Chunk Names index.html 417 bytes [emitted] main.619734f520.css 13 bytes main [emitted] [immutable] main main.619734f520.js 5.22 KiB main [emitted] [immutable] mainTip: 通过入口文件引入的模块都属于一个 chunk。这里 css 是通过入口文件(index.js)引入的,所以 main.js 和 main.css 的 chunkhash 值相同。
contenthashcontenthash 是根据文件内容来的,可以较好的解决以上问题。请看示例:
将 chunkhash 改为 contenthash,然后打包:
// webpack.config.js module.exports = { output: { filename: 'main.[contenthash:10].js', }, plugins: [ new MiniCssExtractPlugin({ filename: "[name].[contenthash:10].css", }) ] } > npm run build > webpack-example3@1.0.0 build > webpack Hash: 12994324788654e2ffc4 Version: webpack 4.46.0 Time: 5115ms Built at: 2021-07-14 9:26:59 ├F10: PM┤ Asset Size Chunks Chunk Names index.html 417 bytes [emitted] main.21668176f0.css 12 bytes main [emitted] [immutable] main main.8983191438.js 5.22 KiB main [emitted] [immutable] main这次,js 和 css 的 hash 值不在相同。通过浏览器访问多次后,main.js 和 main.css 也都被强缓存。
修改css:
p{color:yellow;}