webpack性能优化

447 阅读2分钟

提升webpack打包速度的方法

  • 跟上技术的迭代(Node,Npm,Yarn):webpack版本更新时,内部会做优化,打包速度会提升。webpack运行在Node之上,node升级,webpack打包速度也会变快。npm的升级可以更快速处理包依赖,可以间接提升打包速度

  • 在尽可能少的模块上应用loader:合理使用include和exclude约定文件夹,降低loader被频繁执行的频率

  • plugin尽可能精简并确保可靠

  • resolve参数合理配置:将import Child from './child/child.js;‘简化为import Child from './child/child;,需要配置extensions,但是如果extensions里配置项过多,每次需要调用很多次文件的查找,频繁调用nodejs底层的文件查找,有性能损耗,一般是js,jsx,ts,tsx才会配置到extensions里。alias也要合理配置.

  extensions:['.js','.jsx']
  • 使用DllPlugin提高打包速度:目的-引入的第三方模块只打包一次保存,之后打包不再分析

  • 配置webpack.dll.js文件:将第三方模块单独打包,用library将第三方模块的代码通过全局变量的方式暴露出去,然后借助DLLPlugin插件分析暴露出去的代码,生成manifest.json映射文件

      ```
      const path = require('path');
      const webpack = require('webpack');
      module.exports = {
          mode:'production',
          entry: {
              vendors:['lodash','react','react-dom',]
          },
          output: {
              path: path.resolve(__dirname, '../dll'),
              filename:'[name].dll.js',
              library:'[name]'
          },
          plugins:[
              new webpack.DllPlugin({
                  name: '[name]',
                  path: path.resolve(__dirname, '../dll/[name].manifest.json')
              })
          ]
      }
      ```
    
  • 运行打包命令,生成第三方代码的内容

      ```
      "build:dll": "webpack --config ./build/webpack.dll.js"
      ```
    
  • 配置webpack.common.js,引入AddAssetHtmlWebpackPlugin,将打包的dll文件引入html

      ```
      npm i AddAssetHtmlWebpackPlugin --save
      const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin');
      new AddAssetHtmlWebpackPlugin({
      	filepath: path.resolve(__dirname,'../dll/vendors.dll.js')
      }),
      ```
    
  • 引入DllReferencePlugin,结合生成的dll文件和引入的第三方模块,分析manifest.json,打包时,三方代码直接从生成的dll文件中拿

      ```
      new webpack.DllReferencePlugin({
      	manifest: path.resolve(__dirname,'../dll/vendors.manifest.json')
      })
      ```
    
  • 进一步的用法:将第三方模块分别打包到不同的dll文件

      ```
      entry: {
          vendors:['lodash'],
          react:['react','react-dom',]
      },
      ```
      - 注入
      
      ```
      [
      	new AddAssetHtmlWebpackPlugin({
      		filepath: path.resolve(__dirname, '../dll/vendors.dll.js')
      	}),
      	new AddAssetHtmlWebpackPlugin({
      		filepath: path.resolve(__dirname, '../dll/react.dll.js')
      	}),
      	new webpack.DllReferencePlugin({
      		manifest: path.resolve(__dirname, '../dll/vendors.manifest.json')
      	}),
      	new webpack.DllReferencePlugin({
      		manifest: path.resolve(__dirname, '../dll/react.manifest.json')
      	})
      ],
      ```
    
  • 更方便的写法(Node)

      ```
      const fs = require('fs');
      const plugins = [
      	new HtmlWebpackPlugin({
      		template: 'src/index.html'
      	}),
      	new CleanWebpackPlugin(['dist'], {
      		root: path.resolve(__dirname, '../')
      	}),
      ];
      const files = fs.readdirSync(path.resolve(__dirname, '../dll'));
      console.log(files);
      files.forEach(file => {
      	if (/.*\.dll.js/) {
      		plugins.push(
      			new AddAssetHtmlWebpackPlugin({
      				filepath: path.resolve(__dirname, '../dll', file)
      			})
      		)
      	}
      	if (/.*\.manifest.json/) {
      		plugins.push(
      			new webpack.DllReferencePlugin({
      				manifest: path.resolve(__dirname, '../dll', file)
      			})
      		)
      	}
      })
      ```
    
  • 报错:写法错误 if (/.*\.dll.js/.test(file)) {} if (/.*\.manifest.json/.test(file)) {}

  • 控制包文件大小:拆分代码

  • thread-loader,parallel-webpack,happypack多进程打包:webpack默认通过nodeJs运行的,所以是一个单线程的打包过程。可以借助node里的多进程来提升打包速度。多进程,同时利用多个CPU打包。

  • 合理使用sourceMap

  • 结合stats分析打包结果

  • 开发环境内存编译

  • 开发环境无用插件剔除