webpack5-构建速度提升篇

968 阅读3分钟

背景

duangkey本周新工作第一天,等待系统开通之余,对上周在老东家的最后一次优化做个记录。

公司产品是IOT项目,需要对接视频监控平台以及各种的协议对接,因此项目体积不可避免的大。 为了更好的完成组件的维护工作,使用了verdaccio去管理组件库,项目中所使用的组件都是通过私有库进行安装引入的,组件很多,开源插件也安装了不少。

在没有进行构建优化之前,项目构建耗时有时会达到恐怖的300s,现磨咖啡都能磨四五杯了。

优化策略

项目使用渐进式框架vue进行搭建,版本是vue3,打包工具版本号是webpack5,低版本webpack请谨慎参考;

正常优化手段是借助相关plugin进行配置优化,比如TerserWebpackPlugin、CssMinimizerWebpackPlugin等等

TerserWebpackPlugin:js压缩插件;

CssMinimizerWebpackPlugin:使用cssnano优化和压缩CSS;

(具体配置和介绍可参考官方文档⬆)

下面介绍本次的主角-- esbuild-loader

Speed up your Webpack build with esbuild!

esbuild is a JavaScript bundler written in Go that supports blazing fast ESNext & TypeScript transpilation and JS minification.

esbuild-loader lets you harness the speed of esbuild in your Webpack build by offering faster alternatives for transpilation (eg. babel-loader/ts-loader) and minification (eg. Terser)!

简单来说就是使用esbuild提升webpack构建速度,它是使用Go语言开发的一款JS Bundler,支持超快的ESNext和TS转译以及JS的压缩;它可以使你利用它的速度去代替Terser和babel,也是Terser和babel进行性能优化的替代方案。

这说明我们只需要使用esbuild-loader,就可以实现Terser和babel的功能。

安装

npm i -D esbuild-loader  
OR
yarn add esbuild-loader

vue.config.js的配置 引入esbuild-loader的EsbuildPlugin模块,并在chainWebpack中进行配置

const { EsbuildPlugin } = require('esbuild-loader');

const rule = config.module.rule('js'); // ①
rule.uses.clear(); // ②
rule.use('esbuild-loader').loader('esbuild-loader').options({
      loader: 'jsx',// 3-1
      target: 'es2015' // 3-2
    });   // ③
config.optimization.minimizers.delete('terser');  // ④
config.optimization
      .minimizer('esbuild')
      .use(EsbuildPlugin, [{ target: 'es2015', css: true }]);   //  ⑤
  1. 使用esbuild编译js文件
  2. 清空webpack内置的babel-loader
  3. 添加esbuild-loader
  4. 删除底层terser, 改用esbuild-minimize-plugin
  5. 使用esbuild-loader进行css的压缩 3-1. 使用esbuild-loader编译含有jsx语法的文件 3-2. 编译的目标是es2015规范的文件

问题

配置成功后,构建速度明显提升,看上去貌似没什么问题了。但是,在vue3中如果使用h函数进行node的创建的话,会报react is not defined的错误,这说明此时项目并不能正常解析含有h函数的文件,导致项目启动失败。

解决方法

在options中添加2行配置参数:

jsxFactory: 'h', //自定义jsx解析方案,此处使用h作为渲染函数
jsxFragment: 'Fragment' //默认为 React.Fragment , 换成对应的 Vue.Fragment

保存后重新启动项目,基本可以控制在磨一杯咖啡的时间内了。

【使用speechSynthesis实现文字转语音功能】