通用插件设计 - 使用 SWC & ESBuild 加速你的项目构建
通用插件设计 - 使用 SWC & ESBuild 加速你的项目构建
Webpack 构建提速插件是一整套提升前端项目构建速度的插件,能提供一个通用的解决方案,无需针对项目做特别的配置。
一、背景
背景其实就是我们目前的前端构建速度还是太慢,经常会达到 6、7min 以上,这对于开发效率来说是一个很大的影响。
二、使用方式
总共五个插件体系,可单独使用也可以集合使用:
- 支持 swc 与 esbuild 构建
- 支持 DLL
1 | module.exports = { |
三、插件设计
1. febuilder-improve-plugin
- 插件执行逻辑设计,根据用户插件参数配置
- 开启 esbuild/swc 构建
- 替换 babel-loader 和 TerserPlugin 这两个耗时久的插件
- 参数转换,平滑适配
- 开启 dll 构建优化
- 开启 esbuild/swc 构建
febuilder-improve-plugin 的构建过程,中间在初始化参数之后会在 webpack 的 environment 钩子处将 babel-loader 和 TerserPlugin 自动替换掉,同时针对 babel-loader 到 swc 编译做了一些更平滑的参数适配,尽量保证用户不需要做一些额外的处理,能达到平滑替换。
2. swc-core
- 为什么要整这样一个包?
- 官方提供的包体积特别大(经排查是没有区分不同平台的版本),导致依赖安装速度特别慢(37s)
- 优化效果,依赖安装速度 4s
- 从 37s -> 4s,大致有九倍速度提升
- 从 100M -> 8M,依赖安装体积仅占官方的不到 10%
swc-core 是 swc 最核心的提供编译能力的包,那么我们封装的 swc-core 和官方的有什么区别?或者说为什么要再封装一个?
我们可以看一下左边的这个图,swc 是 RUST 来构建的,不同平台编译会有不同的包来处理,所以会把所有的包都下载下来,然后再根据当前平台和操作系统仅仅保留一个用于编译构建的版本,这就导致一个问题。一个包大概 6-8M 左右,13个包大概 100M,如果说为了提升build的构建速度,而导致依赖安装耗费了更多的时间,显然得不偿失。因此我们基于这种情况做了一些优化。
- 优化手段流程设计
- 利用 npm script 的 post install 钩子
- 手动获取当前平台信息,安装指定版本的文件
如右图所示,我们会放弃默认安装所有文件,而是利用 npm script 的 postinstall, 会在 swc-core 安装后默认执行,然后这个时候我们会手动去获取平台信息,然后在指定位置执行 npm install脚本,安装指定版本的文件,这样就可以保证只下载一个平台的包。
优化结果 100M -> 8M ,然后可以看一下整体的安装耗时,这个耗时都是在 cache clean 之后对比的。优化结果还是比较明显的,不至于说引入我们的包导致依赖安装有更多的耗时。
3. febuilder-dll-plugin
- 为什么要整这样一个包?
- 希望从 DLL 动态链接这个常规角度,提供一个更为方便的构建速度优化方式
流程设计
- 利用 environment 钩子注入插件
- 监听 Run & WatchRun 插入构建逻辑
- 检测 package.json 依赖变化
- contenthash 文件命名,保证浏览器缓存命中
优化提升:配置流程大大简化
- 左侧常规配置,需要启动两次 webapck 构建
- 右侧使用 @shopee/febuilder-dll-plugin 插件,只用一次构建,自动分析
四、总结
插件的收益还是很明显的,经过测试基本有 67% 的速度提升,这个速度提升对于我们的项目来说还是很有意义的,能够提升开发效率,减少等待时间。
- 感谢你的欣赏!