背景
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 }]); // ⑤
- 使用esbuild编译js文件
- 清空webpack内置的babel-loader
- 添加esbuild-loader
- 删除底层terser, 改用esbuild-minimize-plugin
- 使用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
保存后重新启动项目,基本可以控制在磨一杯咖啡的时间内了。