背景

我们使用webpack打包我们的模块化应用程序,webpack会生成一个可部署的 /dist 文件,我们只要将 /dist 文件中的内容部署到 server 上,浏览器就能够访问到我们的网站及资源。而获取资源是比较耗费时间的,因此浏览器使用了一种名为 缓存 的技术。可以通过命中缓存,来降低网络流量加快网站加载速度。但是,如果我们在部署新版本的时候,文件名没有发生改变,浏览器会认为资源没有被更新,从而依旧使用缓存数据
因为缓存的存在,我们在获取新资源会变得比较棘手。

解决方法

输出文件名

  1. output: { // 出口文件
  2. filename: '[name].[contenthash].bundle.js', // 通过配置 contenthash 随机生成字符串
  3. },

提取第三方库

将第三方库提取到单独的文件中是比较推荐的一种做法,因为他们很少像本地代码一样频繁修改,所以我们可以利用浏览器的长效缓存,命中缓存来消除请求。

  1. splitChunks: {
  2. cacheGroups: {
  3. vendor: {
  4. test: /[\\/]node_modules[\\/]/, // 匹配node_modules
  5. name: 'vendors', // 生成第三方库的 name
  6. chunks: 'all',
  7. },
  8. },
  9. }

模块标识符

新增 print.js 模块,编写如下代码:

  1. export default function print(text) {
  2. console.log(text);
  3. };

在 index.js 中引入

  1. import Print from './print';
  2. document.body.appendChild(button.onclick = Print.bind(null, 'Hello webpack!'))

运行 npx webpack,我们的期望是 vendor 名称不变,结果发现所有包的文件名的hash字符串都改变了,这显然不符合我们的需求,所以我们要在 webpack.config.js 中增加一个配置,如下:

  1. optimization: {
  2. moduleIds: 'deterministic',
  3. },

配置好以后我们再次运行 npx webpack,记录一下 vendor 的文件名,然后我们将 index.js 中的引入全都注释掉,再次运行 npx webpack,发现 vendor 的文件名没有发生变化,达到了我们的预期效果。