五、Webpack 生产环境 优化构建速度

七、生产环境 优化构建速度


1. OneOf

作用:让每个规则只匹配一个文件,大大增加构建速度

module里面的rules里,每个规则都会扫一遍全部的文件,这样会大大增加构建的速度,
而加了OneOf,就可以让每个规则只匹配一个文件,大大增加构建速度,但不能有两个配置处理同一种类型文件,如js

//webpack.config.js文件

module: {
    rules: [
      {
        test: /\.js$/, //js语法检查
        exclude: /node_modules/,
        enforce: 'pre', // 优先执行
        loader: 'eslint-loader',
        options: {
          fix: true
        }
      },
      {
        // 以下loader只会匹配一个
        // 注意:不能有两个配置处理同一种类型文件
        oneOf: [
          {
            test: /\.css$/,
            use: [...commonCssLoader]
          },
          {
            test: /\.less$/,
            use: [...commonCssLoader, 'less-loader']
          },
          {
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            options: {
              presets: [
                [
                  '@babel/preset-env',
                  {
                    useBuiltIns: 'usage',
                    corejs: {version: 3},
                    targets: {
                      chrome: '60',
                      firefox: '50'
                    }
                  }
                ]
              ]
            }
          }
          }
        ]
      }
    ]
  },
  
  plugins: [
    new MiniCssExtractPlugin({
      filename: 'css/built.[contenthash:10].css'
    })
    //...
  ],
  // 生产环境
  mode: 'production'
}

2. 缓存

作用:如果已经构建过了且没有变化,则直接读取缓存,如果有变化,则构建后读取

  1. 对babel进行换缓存 只需要在loader: ‘babel-loader’, 加一行cacheDirectory: true就可以实现babel缓存

  2. 对文件资源进行缓存

    当别人访问你的服务时,css、js资源会被强制缓存下来,当下次访问时,不会重新加载资源,而是直接读缓存,
    而决定走缓存还是重新加载资源,是根据资源名字是否改变决定的

    比如a.js 内容为1,index.html引入a.js, 第一次会加载资源,第二次会走缓存,而此时你把a.js内容改为1、2,

    index.html引入a.js,则别人再次访问时,还是会读取内容为1的js,因为a.js名称没变,会一直读取原来的缓存

Webpack中有3种hash值

hash: 每次webpack构建时会生成一个唯一的hash值。

chunkhash:根据chunk生成的hash值。如果打包来源于同一个chunk,那么hash值就一样

contenthash: 根据文件的内容生成hash值。不同文件hash值一定不一样,可以打到改变那个文件,那个文件的文件名改变的效果

使用hash或chunkhash时,如果只改变了css,则会导致css和js都会重新生成一个新的hash值,就会导致改变1个文件,而多个文件同时变化的问题

而contenthash则是根据内容是否改变来决定是否生产新的hash值,不会出现改变css文件,而相关联文件也发生变化的情况,所以对文件资源进行缓存用contenthash

//webpack.config.js文件

module: {
    entry: './src/js/index.js', 
      
    output: {
        filename: 'js/built.[contenthash:10].js', //输出的文件名改为contenthash
        path: resolve(__dirname, 'build'), 
    },
    
    rules: [
      {
        test: /\.js$/, //js语法检查
        exclude: /node_modules/,
        enforce: 'pre', // 优先执行
        loader: 'eslint-loader',
        options: {
          fix: true
        }
      },
      {
        // 以下loader只会匹配一个
        // 注意:不能有两个配置处理同一种类型文件
        oneOf: [
          ../
          {
            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
            }
          }
        ]
      }
    ]
  },

3. 多进程打包

多进程打包:某个任务消耗时间较长会卡顿,多进程可以同一时间干多件事,效率更高。

优点是提升打包速度,缺点是每个进程的开启和交流都会有开销(babel-loader消耗时间最久,所以使用thread-loader针对其进行优化)

建议项目比较大,或者工作消耗时间比较长,才需要多进程打包

安装命令:npm install thread-loader -d

//webpack.config.js文件

module.exports = {
  //...
  module: {
    rules: [
      {  
        test: /\.js$/,  //js的兼容性处理
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          presets: [
            [
              '@babel/preset-env',
              {
                useBuiltIns: 'usage',
                corejs: {
                  version: 3
                },
                targets: {
                  chrome: '60',
                  firefox: '60',
                  ie: '9',
                  safari: '10',
                  edge: '17'
                }
              }
            ]
          ],
          // 开启babel缓存第二次构建时,会读取之前的缓存
          cacheDirectory: true
        }
      //...
    ],
  },
    
  plugins: [
    //...
  ],
  
}

4. dll 动态链接库

dll动态链接库,可以对某些库(第三方库jquery、react、vue…)进行单独打包
作用:只需要一开始对第三方库打包一次,后面再打包时,只需要打包源代码,不再对第三方库打包了,这样编译会快很多

需要新增一个 webpack.dll.js文件

//webpack.dll.js文件
/*
  使用dll技术,对某些库(第三方库:jquery、react、vue...)进行单独打包
    当你运行 webpack 时,默认查找 webpack.config.js 配置文件
    需求:需要运行 webpack.dll.js 文件 
    --> webpack --config webpack.dll.js  
*/

const { resolve } = require('path');
const webpack = require('webpack');

module.exports = {
  entry: {
    // 最终打包生成的[name] --> jquery
    // ['jquery'] --> 要打包的库是jquery
    jquery: ['jquery'],
  },
  output: {
    filename: '[name].js',
    path: resolve(__dirname, 'dll'),
    library: '[name]_[hash]' // 打包的库里面向外暴露出去的内容叫什么名字
  },
  plugins: [
    // 打包生成一个 manifest.json --> 提供和jquery映射
    new webpack.DllPlugin({
      name: '[name]_[hash]', // 映射库的暴露的内容名称
      path: resolve(__dirname, 'dll/manifest.json') // 输出文件路径
    })
  ],
  mode: 'production'
};


//webpack.config.js文件

  //...
  
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    // 告诉webpack哪些库不参与打包,同时使用时的名称也得变~
    new webpack.DllReferencePlugin({
      manifest: resolve(__dirname, 'dll/manifest.json')
    }),
    // 将某个文件打包输出去,并在html中自动引入该资源
    new AddAssetHtmlWebpackPlugin({
      filepath: resolve(__dirname, 'dll/jquery.js')
    })
  ],
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值