webpack性能优化———构建性能优化

129 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情

webpack性能优化———构建性能优化

  • 构建性能

    • 减少模块解析

      • 模块解析是 webpack 构建过程当中的一个关键环节。模块解析包括:抽象语法解析、依赖分析、模块语法替换。
      • 当模块不经过模块解析的时候,该模块文件经过 loader 处理之后的代码就是最终的代码。该模块的源码就是最终打包结构的代码。并且可以缩短项目的构建时间。
      • 当一些第三方库,本身它已经经过了模块解析的步骤了,那我们在项目构建的过程当中,就不需要再对其进行模块解析了,比如:jQuery
      • 那么如何让一个模块不需要进行解析呢?我们可以在webpack.config.js对其进行配置。
        module.exports = {
          module: {
            npParse: /jquery/,
          },
        };
        
        经过上面,我们在 module 当中对属性noParse进行正则匹配,匹配到的模块文件会不经过模块解析这个操作,直接进行打包。忽略大型的 library 可以提高构建性能。
    • 优化 loader 性能

      • 限制 loader 的应用范围

        • 限制 loader 的应用范围的思想和优化模块解析类似,我们可以将那些已经通过 loader 解析过的第三方库不再使用 laoder 进行代码转换。比如babel-loader可以将 js 代码转成 es3 的代码,但是我们在项目当中经常使用的lodash库本身就是使用 es3 来构建的,所以我们将其排除在babel-loader的代码转换之外。

        • 实现方式

          module.exports = {
            module:{
              //定义loader解析规则
              rules:[
                {
                  test:/\.js$/,       //定义模块文件匹配规则
                  use:'babel-laoder',  // 匹配成功使用的模块
                  exclude:/lodash/,   // 排除的模块文件
                }
              ]
            }
          }
          

          如果你想简单一点,我们可以直接将node_modules当中的模块文件全部排除处理,这样项目构建只需要构建src下面的文件,这样项目构建会快很多。

      • 缓存 laoder 结果

        缓存 loader 的结果主要是缓存 loader 转换模块文件之后的代码,假如我们更改了项目当中的某个文件,需要重新构建项目,但是其他的文件并不需要重新构建,我们只需要重新构建修改的文件就好了,其他文件我们可以从 laoder 缓存当中读取,这个功能的实现主要依赖于cache-laoder,它是一个 loader,并不是一个插件,所以使用也需要在rules当中使用。

        module.exports = {
          // ...
          module: {
            rules: [
              {
                test: /\.ext$/, //匹配模块文件的正则
                use: ["cache-laoder", ...loaders], // 当匹配成功使用cache-laoder等loaders进行处理
                include: path.resolve("src"), // 包含处理的目录
              },
            ],
          },
        };
        

        上面我们把cache-laoder放在数组的第一个元素,但是它却可以决定后面的 loader 是否运行。

      • 为 loader 的运行开启多线程

        我们可以在 loader 解析模块文件的时候,为 loader 开启多线程,这样就可以同时转换多个模块文件,大大加快转换速度。

        npm install thread-loader --save-dev
        

        上面的命令安装了一个thread-loader的 loader,它会开启一个线程池,线程池当中包含适量的线程。它会把后续的 loader 放到线程池的线程当中运行,以提高构建效率。

        // webpack.config.js
        module.exports = {
          module:{
            rules:[
              {
                test:/\.js$/,
                use:[
                  "thread-loader",
                ],
                include:path.resolve('src'),
              }
            ]
          }
        }
        

        thread-loader还可以实现很多的自定义配置,详情可以查看官网thread-laoder 官网

    • 开启 HRM 替换

      • 什么叫 HRM? HRM也称为模块热替换(模块热更新),它可以说是 webpack 提供的最有用的功能之一。它允许在运行时更新各种模块,而无需进行完全刷新。

      • 启动 HRM

        启用 HRM 很简单,我们可以下载一个插件webpack-dev-server,或者启用 webpack 的内置 HMR 插件。

        const webpack = require('webapck');
        // webpack.config.js
        module.exports = {
          devServer:{
            hot:true,  // 开启热更新
          }
          plugin:[
            new webpack.NamedModulesPlugin(),    // 查看要修补(patch)的依赖
            new webpack.HotModuleReplacementPlugin()   // 开启模块热更新替换
          ]
        }
        

        接下来我们需要在需要开启热更新的模块文件当中添加接收 HRM:

        //如果检测到模块开启热更新,那么就接受更新。
        if(module.hot){
          module.hot.accept('.print.js',function(){
            console.log('Accepting the updated printMe module!');  //当触发热更新就会在控制台打印
            printMe();
        
          })
        }
        
      • CSS 热替换 借助于 style-loader 的帮助,CSS 的模块热替换实际上是相当简单的。当更新 CSS 依赖模块时,此 loader 在后台使用 module.hot.accept 来修补(patch) <style> 标签。 所以,我们可以先安装下面两个 laoder

        npm install style-laoder css-laoder --save-dev
        

        接下来我们对webpack.config.js进行配置:

        // webapck.config.js
        module.exports = {
          // ...
          module:{
            rules:[
              {
                test:/\.css$/,
                use:['style-laoder','css-laoder'],
        
              }
            ]
          }
        }
        

        接下来我们只需要在我们的 js 文件当中引入 css 样式就好了

        import "./style.css";
        

        当我们修改style.css当中的样式文件的时候,我们会发现,css 也触发了热更新。