美文网首页
Webpack 优化

Webpack 优化

作者: pursuepursuing | 来源:发表于2020-06-29 17:14 被阅读0次

    构建优化

    缩小文件搜索范围

    优化 loader 配置

    通过testincludeexclude三个配置项,减少loader处理的文件

    优化 resolve.modules 配置

    当安装的第三方模块都放在项目根目录下的./node_modules目录下时,没有必要按照默认的方式去一层层的寻找,可以指明存放第三方模块的绝对路径,以减少寻找。

    module.exports = {
      resolve: {
        // 使用绝对路径指明第三方模块存放的位置,以减少搜索步骤
        // 其中 __dirname 表示当前工作目录,也就是项目根目录
        modules: [path.resolve(__dirname, 'node_modules')]
      },
    };
    

    优化 module.noParse 配置

    module.noParse配置项可以让 Webpack 忽略对部分没采用模块化的文件的递归解析处理,这样做的好处是能提高构建性能。

    module.exports = {
      module: {
        // index.html中外部链接引入的文件
        noParse: [/jquery|lodash/],
      },
    };
    

    使用 HappyPack

    在整个 Webpack 构建流程中,最耗时的流程可能就是 Loader 对文件的转换操作了,因为要转换的文件数据巨多,而且这些转换操作都只能一个个挨着处理。 HappyPack 的核心原理就是把这部分任务分解到多个进程去并行处理,从而减少了总的构建时间。

    安装依赖

    npm i -D happypack
    

    接入配置

    const HappyPack = require('happypack');
    
    const os = require('os'); // node 提供的系统操作模块
    // 构造出共享进程池,根据我的系统的内核数量 指定线程池个数 也可以其他数量
    const happyThreadPool = HappyPack.ThreadPool({size: os.cpus().length});
    
    module.exports = {
      module: {
        rules: [
          {
            test: /\.js$/,
            // 把对 .js 文件的处理转交给 id 为 babel 的 HappyPack 实例
            use: ['happypack/loader?id=babel'],
            // 排除 node_modules 目录下的文件,node_modules 目录下的文件都是采用的 ES5 语法,没必要再通过 Babel 去转换
            exclude: path.resolve(__dirname, 'node_modules'),
          },
          {
            // 把对 .css 文件的处理转交给 id 为 css 的 HappyPack 实例
            test: /\.css$/,
            use: ExtractTextPlugin.extract({
              use: ['happypack/loader?id=css'],
            }),
          },
        ]
      },
      plugins: [
        new HappyPack({
          // 用唯一的标识符 id 来代表当前的 HappyPack 是用来处理一类特定的文件
          id: 'babel',
          // 如何处理 .js 文件,用法和 Loader 配置中一样
          loaders: ['babel-loader?cacheDirectory'],
          // 使用共享进程池中的子进程去处理任务
          threadPool: happyThreadPool,
        }),
        new HappyPack({
          id: 'css',
          // 如何处理 .css 文件,用法和 Loader 配置中一样
          loaders: ['css-loader'],
          // 使用共享进程池中的子进程去处理任务
          threadPool: happyThreadPool,
        })
      ],
    };
    

    使用 ParallelUglifyPlugin

    由于压缩 JavaScript 代码需要先把代码解析成用 Object 抽象表示的 AST 语法树,再去应用各种规则分析和处理 AST,导致这个过程计算量巨大,耗时非常多。

    当 Webpack 有多个 JavaScript 文件需要输出和压缩时,原本会使用 UglifyJS 去一个个挨着压缩再输出, 但是 ParallelUglifyPlugin 则会开启多个子进程,把对多个文件的压缩工作分配给多个子进程去完成,每个子进程其实还是通过 UglifyJS 去压缩代码,但是变成了并行执行。 所以 ParallelUglifyPlugin 能更快的完成对多个文件的压缩工作。

    npm i -D webpack-parallel-uglify-plugin
    
    
    const path = require('path');
    const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');
    
    module.exports = {
      plugins: [
        // 使用 ParallelUglifyPlugin 并行压缩输出的 JS 代码
        new ParallelUglifyPlugin({
          //开启几个子进程去并发的执行压缩。默认是当前运行电脑的 CPU 核数减去1。 
          workerCount: 4,
          // 传递给 UglifyJS 的参数
          uglifyJS: {
            output: {
              // 最紧凑的输出
              beautify: false,
              // 删除所有的注释
              comments: false,
            },
            compress: {
              // 在UglifyJs删除没有用到的代码时不输出警告
              warnings: false,
              // 删除所有的 `console` 语句,可以兼容ie浏览器
              drop_console: true,
              // 内嵌定义了但是只用到一次的变量
              collapse_vars: true,
              // 提取出出现多次但是没有定义成变量去引用的静态值
              reduce_vars: true,
            }
          },
        }),
      ],
    };
    

    输出质量优化

    使用imagemin-webpack-plugin插件

    import ImageminPlugin from 'imagemin-webpack-plugin'
    
    module.exports = {
      plugins: [
        // Make sure that the plugin is after any plugins that add images
        new ImageminPlugin({
          disable: process.env.NODE_ENV !== 'production', // Disable during development
          test: /\.(gif|png|jpe?g|svg)$/i,
          onlyUseIfSmaller: true,
          pngquant: {
            quality: '65-80'
          }
        })
      ]
    }
    

    chainWebpack配置

    import ImageminWebpackPlugin from 'imagemin-webpack-plugin';
    
    module.exports = {
        chainWebpack: config => {
          config.plugin('imagemin-webpack-plugin')
           .use(ImageminWebpackPlugin, [
             {
               disable: process.env.NODE_ENV !== 'production'
               test: /\.(gif|png|jpe?g|svg)$/i,
               onlyUseIfSmaller: true,
               pngquant: {
                quality: '65-80'
               }
             }
          ]);
        }
    }
    

    提取公共代码

    将所有从node_modules的引用打包到一个名字叫vendor的chunk

    module.exports = {
      //...
      optimization: {
        splitChunks: {
          cacheGroups: {
            commons: {
              test: /[\\/]node_modules[\\/]/,
              name: 'vendors',
              chunks: 'all'
            }
          }
        }
      }
    };
    

    相关文章

      网友评论

          本文标题:Webpack 优化

          本文链接:https://www.haomeiwen.com/subject/immlxktx.html