什么是文件指纹

打包输出的文件名的后缀就是文件指纹。
使用它好处是,在文件指纹没有发生改变的时候,浏览器会加载被缓存的资源文件。
只在文件内容发生改变,才有新的文件指纹,浏览器才会请求新的资源文件。

文件指纹的三种方式

hash

整个项目只要项目文件有修改,构建的hash值就会变。举例:

  1. // webpack.prod.js
  2. entry: {
  3. index: "./src/index",
  4. search: "./src/search"
  5. },
  6. output: {
  7. path: path.join(__dirname, "dist"),
  8. filename: "[name]_[hash:8].js",
  9. publicPath: "./dist"
  10. }

注::8代表只截取hash值的前8位

它的问题在于,两个entry打包出来的文件hash是相同的,任何一个依赖的资源变化,两个hash值都会发生变化。

chunkhash

和打包的chunk有关,不同的entry有不同的chunkhash值。它能避免一个chunk改变而重新给另一个chunk新的指纹。

contenthash

根据文件内容来定义hash,文件内容不变则contenthash不变。它的应用场景是CSS,并且它是属于MiniCssExtractPlugin插件提供的用法。举例:

  1. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  2. modle.exports = {
  3. plugins: [
  4. new MiniCssExtractPlugin({
  5. filename: '[name]_[contenthash:8].css'
  6. })
  7. ],
  8. module: {
  9. {
  10. test: /\.css$/, use: [MiniCssExtractPlugin.loader,'css-loader']
  11. }
  12. }
  13. }

只要有CSS文件的内容发生了变化,就会bulid出新的文件名。

实际应用

上述配置直接可以使用,但是需要将mode改为’production’, 并且将devServer和plugins中的HotModuleReplacementPlugin注释掉。

比较好的做法是,另外拷贝一个 webpack.prod.js出来,在package.json中通过如下命令指定运行

  1. "scripts": {
  2. "build": "webpack --config webpack.prod.js",
  3. }

图片的文件指纹

图片、字体的文件指纹和上述不一样,需要使用file-loader,并且它的占位符中 hash 就是代表的文件内容。

  1. module.exporst = {
  2. module: {
  3. rules: [{
  4. test: /\.(png|jpe?g|gif)$/i,
  5. use: [{
  6. loader: 'file-loader',
  7. options: {
  8. name: '[name]_[hash:8].[ext]'
  9. }
  10. }]
  11. },{
  12. test: /\.(woff|woff2|eot|ttf|otf)$/,
  13. use: [{
  14. loader: 'file-loader',
  15. options: {
  16. name: '[name]_[hash:8].[ext]'
  17. }
  18. }]
  19. }]
  20. }
  21. }

注:省略了无关的配置代码。