# Webpack 与浏览器缓存(Caching)
今天我们来讲一下 webpack
与浏览器缓存这一块内容。
想象一个场景,当我们的代码已经打包好的 dist
目录放到的服务器上,
当用户第一次访问 index.html
页面的时候,他会先下载我们所需的 vendors.chunk.js
和 main.bundle.js
两个文件,然后在刷新一下页面,他其实不会再向向服务器请求上面两个 js
文件了,直接从浏览器的缓存中读取使用了。因为两个 js
文件的名字没有改变过。
假设我们的业务代码进行修改了,我们重新打包,发现打包出来的代码还是上图所示。这个时候我们再将代码部署到服务器上,用户访问页面的时候,发现还是这两个名字的 js
,于是就又使用了浏览器缓存中的文件。
因此我们需要对打包出来的 js
文件做一个名字上的配置。
# 一个例子
我们修改入口文件 index.js
:
import _ from 'lodash';
import $ from 'jquery';
const dom = $('<div>');
dom.html(_.join(['Hello', 'darrell'], ' '));
$('body').append();
引入 lodash
和 jquery
文件,在页面上插入 <div>Hello darrell</div>
元素。
我们修改线上配置文件 webpack.prod.js
的 output
配置,在输出的文件名字上加上相应的 [contenthash]
占位符,顾名思义,contenthash
就是根据文件内容生成的 hash
值,只有当文件内容发生改变的时候,才会发生改变:
...
const prodConfig = {
...
output: {
filename: "[name].[contenthash].js",
chunkFilename: '[name].[contenthash].js', // 简介引入代码输出的名字
path: path.resolve(__dirname, '../dist')
}
...
}
...
我们打包一下 npm run build
:
我们会发现有一个警告,这个是 webpack
告诉我们我们打包出来的文件有点大,在性能上可能会有一些问题,这里我们可以暂时先不管,在 webpack.common.js
中加入:
...
module.exports = {
...
performance: false, // 关闭性能上的一些问题
...
}
...
我们重新打包,可以看到打包出来的内容如下:
打包出来的内容中 main
开头的是我们的业务代码,然后 vendors
开头的就是我们的库代码,也就是 lodash
与 jquery
。
接着我们修改一下 index.js
文件:
import _ from 'lodash';
import $ from 'jquery';
const dom = $('<div>');
- dom.html(_.join(['Hello', 'darrell'], ' '));
+ dom.html(_.join(['Hello', 'darrell123'], ' '));
$('body').append();
重新打包,可以看到打包出来 业务代码内容的 hash
变了,而库代码的内容 hash
没变。
这个时候用户重新访问我们的页面,js
的文件名字变了,这个时候便又会从服务器上面重新下载新的文件。而库对应的文件名字没有变,就还是会使用浏览器缓存中的代码。
# 老版本 Webpack
老版本的 Webpack
中的 contenthash
有的时候即使你的内容没有变化,他还是会改变 contenthash
的值,
原因是我们的业务代码和库代码之间有一些关联代码,在 webpack
中被称为 mainfest
,默认情况下 mainfest
的代码会存在于 main.js
和 vendors.js
代码之中的,他在旧版的 webpack
中打包可能会有差异,所以才会造成我们的内容没有变化,但是 contenthash
的值变化了。
这个时候需要在公共配置文件 webpack.common.js
中增加一个配置:
...
module.exports = {
...
optimization: {
...
runtimeChunk: {
name: 'runtime',
},
...
},
...
}
...
我们重新进行打包,会发现 dist
目录下多了 runtime
开头的一个文件:
上面的配置的意思就是将 manifest
关联代码抽离出来放到 runtime.js
中去,main.js
只写业务代码,vendors.js
只放库文件代码。
这个的时候在老版的 webpack
中也不会有相应的问题了。
# 相关链接
# 示例代码
示例代码可以看这里: