麻辣GIS微信平台

更多 GIS 干货

微信关注不错过

「GIS技巧」使用ESBuild加速WebGIS项目前端打包速度(测试提速50%)

最近接手了一个WebGIS老项目,使用的各项技术栈有点老,在加了一个需求及改造之后,跌跌撞撞倒也满足了客户需求。但是幺蛾子总会出的,在五月底项目上线的时候突然被卡住了,部署不了,后来排查发现,因为云效的构建总时长有限制,我们5月的钱用完了。后来实在没办法换Github自带的构建工具临时救个急。具体方案可以参考:「GIS工具」使用Github Actions自动化部署你的GIS应用

事后我们老大说:要不你优化下那个WebGIS项目的前端打包速度吧。

我:好的(内心有点活动)

为了给项目节省资源(给公司省钱),我开始了这个踩坑这旅。

项目背景

这个前端GIS项目使用的工程化设施有点久远,原始项目使用的是 Webpack3 + Ant-Design 3 + Mobx + echart 4,其实就是基于地理信息做了一个数据的可视化展示,甚至称为WebGIS项目我都觉得有点牵强,功能不复杂,业务流也还OK,但前前后后总共写了接近400多个路由页面,所以每次打包至少要生成400+个js文件还要加上静态资源,这个配置慢倒也是正常。

既然要优化打包速度,那就从Webpack的打包脚本入手了,大约梳理了一下构建脚本需要处理的工作如下:

  1. 基础loader处理工作(如js、less、图片)
  2. dll公共包处理
  3. Ant-Design 3 与 ant-design 4 共存(这是另外一个故事)
  4. 注入环境变量
  5. ES-Lint检查
  6. 其他项目运行相关

所以项目的打包构建脚本中有不少历史包袱,在改造的同时需保证原项目所有功能正常运行。

找到的解决方案

在网上找了一圈解决方案,大约整理如下:

  1. 升级 Webpack
  2. 使用 Vite 重写
  3. 使用 ESBuild 重写
  4. 使用 esbuild-loader “无痛”改造

最后选了方案4.

对比了一下,其实开始想使用方案一,也就是升级webpack版本,但时间有点紧,需要把之前所以的配置重写,在 webpack 配置这块我也不是特别有经验,于是做为备选。方案2和3也是一样,需要重新搭建脚手架,可能需要排在后期来尝试。

接入方法

esbuild-loader 这个插件顾名思义,就是把esbuild的能力包装成Webpack的loader来实现js、ts、css等资源的打包编译。

安装 esbuild-loader

// npm
npm i -D esbuild-loader

//yarn
yarn add -D esbuild-loader 

配置loader

esbuilder-loader支持绝大部分前端常用的文件类型打包,本项目中主要是前端js页面文件打包比较耗时,所以只替换了js文件相关的打包部分。

rules: [
  {
    test: /\.(js|jsx)$/,
    loader: 'esbuild-loader',
    options: {
      loader: 'tsx',
      target: 'es2015',
      // 定义你需要的环境变量
      define: {
        ENV: JSON.stringify(process.env.ENV || 'dev'),
      }
    },
    include: path.join(__dirname, 'src'),
    exclude: /(node_modules)/
  },
  // other rules
]

这里为啥.jsx使用的是tsx的loader?这个后面在问题里再细说。

PS:真实项目中改造其实更加复杂,这里只是一个简单的demo,由于相关问题都是具体项目相关,这里不赘述了。

效果实测试

使用原来的happypack的打包时间

优化后的打包时间:

从42s变成21s,速度提升50%。

遇到的问题

改造过程中遇到了不少问题,这里也统一记录一下。

环境变量丢失

原来使用DefinePlugin完成的操作。

解决方案要手动转移到esbuild-loaderdefine字段。

mobx失效

因为mobx使用的是@装饰器,但esbuild-loader中的jsx不支持装饰器语法。

解决方案是使用tsx的loader。

less样式丢失

因为原来的ant-design 3的样式是通过babel-import-plugin实现的,esbuild-loader目前不支持。

解决方案全局引入ant-design样式

不支持原生esbuild插件

esbuild-loader使用的是esbuildtrasform API,而它的插件是使用build方法时注入的。这个的详细内容可以参考:

Possibility of using esbuild plugins · Discussion #119 · privatenumber/esbuild-loader

方案总结

使用esbuild-loader可以快速将老项目中的loader替换,借用esbuild的能力实现前端工程的快速打包构建。

优点

  1. 改造小,几乎是开着火车换轮子式的外科手术操作,对项目影响最小,时间就是生命。
  2. 速度提升明显,尤其是对于页面繁多的老工程项目。

缺点

  1. 没那么快(我个人猜测完全改造成vite会更快)
  2. 功能还比较简陋,不支持原生插件,还是要踩不少坑

后续规划

  1. 如果时间允许,想尝试直接转 vite。
  2. 如果时间紧,那就尝试升级下webpack版本(大概率是这条路子)

欢迎有相关经验的大佬留言提出更好的方案。

相关阅读

麻辣GIS-Sailor

作者:

GIS爱好者,学GIS,更爱玩GIS。

声明

1.本文所分享的所有需要用户下载使用的内容(包括但不限于软件、数据、图片)来自于网络或者麻辣GIS粉丝自行分享,版权归该下载资源的合法拥有者所有,如有侵权请第一时间联系本站删除。

2.下载内容仅限个人学习使用,请切勿用作商用等其他用途,否则后果自负。

手机阅读
公众号关注
知识星球
手机阅读
麻辣GIS微信公众号关注
最新GIS干货
关注麻辣GIS知识星球
私享圈子

留言板(小编看到第一时间回复)