组里的超大前端工程依赖项升级,node版本从node14 升级到node16。这个项目被测试测了两周左右,终于过测,然后上线了。

上线的第一周发现了一个问题,这个问题埋藏很深,只在生产环境才能暴露出来。

表象:
我们平台大量使用了highcharts组件做数据可视化。

这里highchars的常见图(area, line, column, bubble, pie)等图都可以正常显示。但是treeMap图、heatMap图表现不正常。但生产环境不报错。

(treeMap图全白。heatMap图有网格,无色块。)

这个表现在开发、测试环境均不出现,也排除了数据问题。没办法只能本地使用生产环境配置进行编译,将编译产物在本地用nginx代理起来,观察现象。

本地环境调试了很久,终于被我发现了一个报错
Uncaught TypeError: Cannot read properties of undefined (reading 'old')

// source文件源码截取
getPlotLinePath: function(t) {
var e, i, n, r, s, a = this, o = a.chart, h = a.left, c = a.top, d = t.old, p = t.value, f = t.translatedValue, m = t.lineWidth, g = t.force, v = d && o.oldChartHeight || o.chartHeight, y = d && o.oldChartWidth || o.chartWidth, b = a.transB, _ = function(t, e, i) {
return ("pass" !== g && t < e || t > i) && (g ? t = Math.min(Math.max(e, t), i) : s = !0),
t
};

分析:

全局搜索getPlotLinePath,没有这个方法名,说明这是某个依赖源码里面的方法名。看样子是highcharts的源码。

去highcharts的源码里找了一下,报错的地方确实是highcharts的源码。

我们梳理一下现有的信息,再思考一下,问题出在哪里。

node14 + highcharts固定版本,开发测试环境没问题,生产环境没问题。
node16 + highcharts固定版本,开发测试环境没问题,生产环境有问题。

排除highcharts版本问题,排除highcharts源码问题。
node16的开发测试环境又没问题,那么问题只能出在node16版本下生产环境的编译阶段。

开始逐步测试,把一些生产环境特有的配置项给关掉。
关掉一部分,编译一次,查看问题是否依然存在;最终发现问题出在 uglifyjs-webpack-plugin。
只要把uglifyjs-webpack-plugin的功能关闭,生产环境的表现就正常。

uglifyjs-webpack-plugin用于代码的压缩、console的去除等减小代码体积的操作。项目里使用的uglifyjs-webpack-plugin的版本是2.2.0。 2.2.0是uglify-webpack-plugin的最后一个版本,这个版本发布于五年前 (行文时间2024-11-04)。
image.png

我猜测,在node16环境下运行uglifyjs-webpack-plugin@2.2.0进行代码压缩,导致了highcharts代码中某些关键变量丢失、或者函数重命名之后无法对齐上下文。

解决方式:
用terser-webpack-plugin替换uglifyjs-webpack-plugin。
image.png

开始直接装terser-webpack-plugin@5.3.10,发现有冲突装不上。
我们的老项目,装terser-webpack-plugin@1.4.6可以装上。 (而且1.4.6的更新时间是3个月前,真让人感动)

把terser-webpack-plugin的各种配置项设置好,替换掉uglifyjs-webpack-plugin,编译代码,nginx代理运行,观察页面表现,正常了。

完结,撒花!

同步更新到自己的语雀
https://www.yuque.com/dirackeeko/blog/mudc4g0x32o3k4fp


DiracKeeko
125 声望2 粉丝