babel缓存

作用:让第二次打包构建速度更快
问题:

  • HMR功能是基于devServer的,devServer只能应用于开发环境,生产环境不适用!
  • 生产环境打包时,假设有100个js文件,只改动其中一个,其余99个应该不需要重新被打包
  1. const { resolve } = require('path');
  2. const HtmlWebpackPlugin = require('html-webpack-plugin');
  3. // 定义nodejs环境变量:决定使用browserslist的哪个环境
  4. process.env.NODE_ENV = 'production';
  5. module.exports = {
  6. entry: './src/js/index.js',
  7. output: {
  8. filename: 'js/built.[contenthash:10].js',
  9. path: resolve(__dirname, 'build')
  10. },
  11. module: {
  12. rules: [
  13. {
  14. // 在package.json中eslintConfig --> airbnb
  15. test: /\.js$/,
  16. exclude: /node_modules/,
  17. // 优先执行
  18. enforce: 'pre',
  19. loader: 'eslint-loader',
  20. options: {
  21. fix: true
  22. }
  23. },
  24. {
  25. // 以下loader只会匹配一个
  26. // 注意:不能有两个配置处理同一种类型文件
  27. oneOf: [
  28. /*
  29. 正常来讲,一个文件只能被一个loader处理。
  30. 当一个文件要被多个loader处理,那么一定要指定loader执行的先后顺序:
  31. 先执行eslint 在执行babel
  32. */
  33. {
  34. test: /\.js$/,
  35. exclude: /node_modules/,
  36. loader: 'babel-loader',
  37. options: {
  38. presets: [
  39. [
  40. '@babel/preset-env',
  41. {
  42. useBuiltIns: 'usage',
  43. corejs: { version: 3 },
  44. targets: {
  45. chrome: '60',
  46. firefox: '50'
  47. }
  48. }
  49. ]
  50. ],
  51. // 开启babel缓存
  52. // 第二次构建时,会读取之前的缓存
  53. cacheDirectory: true
  54. }
  55. }
  56. ]
  57. }
  58. ]
  59. },
  60. plugins: [
  61. new HtmlWebpackPlugin({
  62. template: './src/index.html',
  63. minify: {
  64. collapseWhitespace: true,
  65. removeComments: true
  66. }
  67. })
  68. ],
  69. mode: 'production',
  70. devtool: 'source-map'
  71. };

文件资源缓存

  • hash:每次wepack构建时会生成一个唯一的hash值。
    • 问题:因为js和css同时使用一个hash值。如果重新打包,会导致所有缓存失效。(只改动一个文件时,导致所有都重新打包)
  • chunkhash:根据chunk生成的hash值。如果打包来源于同一个chunk,那么hash值就一样。
    • 问题:js和css的hash值还是一样的(因为css是在js中被引入的,所以同属于一个chunk)
  • contenthash:根据文件的内容生成hash值。不同文件hash值一定不一样。(让代码上线运行缓存更好使用) ```javascript const { resolve } = require(‘path’); const MiniCssExtractPlugin = require(‘mini-css-extract-plugin’); const OptimizeCssAssetsWebpackPlugin = require(‘optimize-css-assets-webpack-plugin’); const HtmlWebpackPlugin = require(‘html-webpack-plugin’);

// 定义nodejs环境变量:决定使用browserslist的哪个环境 process.env.NODE_ENV = ‘production’;

module.exports = { entry: ‘./src/js/index.js’, output: { filename: ‘js/built.[contenthash:10].js’, path: resolve(__dirname, ‘build’) }, module: { rules: [

  1. ]

}, plugins: [ new MiniCssExtractPlugin({ filename: ‘css/built.[contenthash:10].css’ }), new OptimizeCssAssetsWebpackPlugin(), new HtmlWebpackPlugin({ template: ‘./src/index.html’, minify: { collapseWhitespace: true, removeComments: true } }) ], mode: ‘production’, devtool: ‘source-map’ };

<a name="kVrl5"></a>
# 完整案例
```javascript
const { resolve } = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

/*
  缓存:
    babel缓存
      cacheDirectory: true
      --> 让第二次打包构建速度更快
    文件资源缓存
      hash: 每次wepack构建时会生成一个唯一的hash值。
        问题: 因为js和css同时使用一个hash值。
          如果重新打包,会导致所有缓存失效。(可能我却只改动一个文件)
      chunkhash:根据chunk生成的hash值。如果打包来源于同一个chunk,那么hash值就一样
        问题: js和css的hash值还是一样的
          因为css是在js中被引入的,所以同属于一个chunk
      contenthash: 根据文件的内容生成hash值。不同文件hash值一定不一样    
      --> 让代码上线运行缓存更好使用
*/

// 定义nodejs环境变量:决定使用browserslist的哪个环境
process.env.NODE_ENV = 'production';

// 复用loader
const commonCssLoader = [
  MiniCssExtractPlugin.loader,
  'css-loader',
  {
    // 还需要在package.json中定义browserslist
    loader: 'postcss-loader',
    options: {
      ident: 'postcss',
      plugins: () => [require('postcss-preset-env')()]
    }
  }
];

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'js/built.[contenthash:10].js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        // 在package.json中eslintConfig --> airbnb
        test: /\.js$/,
        exclude: /node_modules/,
        // 优先执行
        enforce: 'pre',
        loader: 'eslint-loader',
        options: {
          fix: true
        }
      },
      {
        // 以下loader只会匹配一个
        // 注意:不能有两个配置处理同一种类型文件
        oneOf: [
          {
            test: /\.css$/,
            use: [...commonCssLoader]
          },
          {
            test: /\.less$/,
            use: [...commonCssLoader, 'less-loader']
          },
          /*
            正常来讲,一个文件只能被一个loader处理。
            当一个文件要被多个loader处理,那么一定要指定loader执行的先后顺序:
              先执行eslint 在执行babel
          */
          {
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            options: {
              presets: [
                [
                  '@babel/preset-env',
                  {
                    useBuiltIns: 'usage',
                    corejs: { version: 3 },
                    targets: {
                      chrome: '60',
                      firefox: '50'
                    }
                  }
                ]
              ],
              // 开启babel缓存
              // 第二次构建时,会读取之前的缓存
              cacheDirectory: true
            }
          },
          {
            test: /\.(jpg|png|gif)/,
            loader: 'url-loader',
            options: {
              limit: 8 * 1024,
              name: '[hash:10].[ext]',
              outputPath: 'imgs',
              esModule: false
            }
          },
          {
            test: /\.html$/,
            loader: 'html-loader'
          },
          {
            exclude: /\.(js|css|less|html|jpg|png|gif)/,
            loader: 'file-loader',
            options: {
              outputPath: 'media'
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: 'css/built.[contenthash:10].css'
    }),
    new OptimizeCssAssetsWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: './src/index.html',
      minify: {
        collapseWhitespace: true,
        removeComments: true
      }
    })
  ],
  mode: 'production',
  devtool: 'source-map'
};