lhlGitHub / trisome

前端大厂进攻学习资料库
21 stars 1 forks source link

说说Webpack hash、chuckhash、 contenthash的区别,分别应用于什么场景? #37

Open lhlGitHub opened 2 years ago

Moannas commented 2 years ago

webpack对输出文件名可以有三种hash值:

  1. hash
  2. chunkhash
  3. contenthash

为什么需要hash?

浏览器会缓存我们的文件。

优点是浏览器读取缓存的文件,能带来更佳的用户体验(不需要额外流量,速度更快);

缺点是有时候我们修改了文件内容,但是浏览器依然读取缓存的文件(也就是旧文件),导致用户看到的文件不是最新的。

这也是为什么以前有时需要在js文件后面拼接上一个版本号

eg: https://xxx.cdn.cn/index.js?version=1.1

hash hash是项目级别的,使用hash的缺点是假如我只改了其中一个文件,但是所有文件的文件名里面的hash都是一样的。

这样会导致本来应该被浏览器缓存的文件,强制要去服务器读取一遍,网络请求数变多了,页面加载有可能就变慢了,用户体验就差了。

有没有可能做到只有改变了文件,hash值才变,而没有改变的文件,文件名里面的hash值就不变呢? chunkhash可以做到这一点

chunkhash chunkhash根据不同的入口文件(Entry)进行依赖文件解析、构建对应的chunk,生成对应的哈希值。

在生产环境里把一些公共库和程序入口文件区分开,单独打包构建,接着我们采用chunkhash的方式生成哈希值,那么只要我们不改动公共库的代码,就可以保证其哈希值不会受影响。

随便修改了index.js中的一点东西

第二次打包

第二次打包后发现打包出来的test.js的hash值并没有变化,app.js的hash和第一次的hash不一样了,说明chunkhash做到了,只改变修改的文件的hash。

但是为什么css文件的hash和app文件的hash是一样的,但是css文件并没有被修改,是因为css文件是被import到了index.js中的,css文件和index.js建立了依赖关系,所有它们的chunkhash是一样的,这样还是存在缓存没有被充分利用的问题。

contenthash contenthash是针对文件内容级别的,只有你自己模块的内容变了,那么hash值才改变。

可以通过contenthash解决上面的问题。