记录一次Vite打包线上某机型白屏故障

2,195 阅读3分钟

一个风和日丽的一天,简简单单的一个页面上线过后,测试同学找过来,说有个IphoneX的机器打不开页面,也就是俗称的白屏,事情由此展开。

一般前端遇到白屏问题,都是先三板斧:测试环境复现 + sentry日志 + 抓接口请求,跟组内的小伙伴打了声招呼,就去忙别的了……一个小时以后,表示没发现业务代码问题。

好消息是测试环境在此机型上可以稳定复现白屏情况,于是在测试环境打开eruda,发现确实有报错,只是没有详细信息,只有个'script error',问了下抓包情况,发现资源都只请求了一部分,那大概率锅在前端,由于只是此机型复现,大概率定位是兼容性问题。

整理了一下已有信息:

  • IOS的手机 safari为12.1版本
  • 报错sentry没上报,说明初始化脚本就挂了
  • 当前白屏的页面是用Vite打包的页面

尤其是第三条信息,我有点不太淡定,因为Vite打包项目确实可能会有兼容性问题,但一直认为IOS12是支持proxy的,不至于运行不了Vue3的页面,并且项目也配置了plugin-legacy,按说兼容性已经拉满了,看来要不是打包有bug,要不是配置不太对,当下要紧的是把真实的错误信息找到。

查了下IOS调试页面的办法,这里费了点时间,因为连上MAC后没出现debug工具,safari打开页面倒还算顺利,还好通过小伙伴提示才在手机上找到了对应设置项,才打开debugger工具。 这里有个知识点:用vconsole或者eruda这类调试工具,如果是通过CDN加载,为了安全期间,window.onError的详细信息不会给到调试工具,只会有个script error的展示,但通过连接上电脑的debugger工具,可以展示出真正的错误原因,这个对于IOS和Android都是一样的。

连接电脑上的调试工具后,错误信息果然出现,报错是不识别globalThis这个变量,这个是打包常用的变量,看起来兼容性问题就在这里,于是用这个手机打开了Vite项目中的其他页面,果然都是同一个错误,看起来就是打包设置哪里不对,不过要先做最小化验证,打开canIUse得到如下信息:

image.png

好家伙,这safari12.1这是卡到bug了,看起来就是打包针对globalThis的ployfill没加进去,打包配置得看一下了,这是当前项目里面的配置:

image.png 盲猜这个safari12.1的占有率肯定达不到0.5%,所以没增加这个ployfill,但是我们的客户端支持IOS12,所以这个兼容得加上,那具体的配置方案是什么呢?

我个人查找了Vite的issue,大概有两种选择,手动挡和自动挡。 先上自动挡:

image.png plugin-legacy的配置如上,加上Vite的build里面配置target为'chrome63',用Vite维护者的话就是可以解决所有兼容性问题,目前我们在项目里面也是这么配置的。为推荐的解决方案

手动挡则是把需要polyfill的内容手动添加上,modernPolyfills要传入一个数组,数组里面是需要polyfill的包,感兴趣的可以查一下针对globalThis的包的写法。至于polyfills的写法,我建议还是借用browserlist的那种,而不是一个个列上去。

image.png

经过更新配置后重新打包,页面成功在当前设备打开,并且其他页面的打开也没有任何问题了~

虽然费了一番功夫,但可以看出最关键的一步是找出详细的报错信息,所以铁子们学到了吗?