前言
周一刚来上班,测试同事反馈说在mac的safari浏览器打不开网页,一直在loading,控制台提示有报错。
报错如下:
然后Google浏览器是正常的,让我排查看下是什么原因。
我本身又是window电脑,周一就来大招,有点挑战。
排查
点开错误前面的箭头,因为是压缩后的代码,没有看到有用的信息,只是提示这个js文件有报错,但是没有具体指向哪段代码。
控制台错误的提示是不期望的"=",网上搜索相关的错误,没有找到。
那就得搜索 "=" 相关的代码,一搜索,好家伙,有几百处地方,那就得一个一个地方排查。
然后我还打印了safari的userAgent,显示是13.x.x。
呕心沥血,最后排查有个可疑地方,使用了逻辑或赋值运算符,这是es2021新语法,会不会是不兼容语法导致的呢?
然后去caniuse网站查看一下兼容性
可以看到,safari 13版本不支持逻辑或赋值运算符,需要safari14及以上才支持,那应该就是这个原因导致了。
接下来就要看看怎么兼容。
解决
修改.browserslistrc文件
我们默认的 .browserslistrc文件是
> 1%
last 2 versions
not dead
只考虑还在维护的浏览器(过滤不再维护的浏览器比如IE8,IE9等),以及使用率大于1%的或者最近的两个版本。
推荐这个网站,可以输入条件然后过滤出哪些浏览器。
可以看到受众覆盖达到77%,然后我们发现筛选的safari没有13版本,得放宽条件才可以。
使用率改成大于0.2%,受众覆盖达到88.5%,safari 9都涵盖了,应该没有问题。
修改后的 .browserslistrc
> 0.2%
last 2 versions
not dead
重新打包,会转义该语法为兼容性语法。
注意:不过这种会把很多语法一起转义,导致打包的体积会变大。
babel转义对应的语法
因为我们使用的是逻辑或赋值运算符||=,类似的还有空值操作运算符??,可选链运算符?.。我们可以专门针对这些语法做转义,这样打包的体积相差不大。
引入babel对应的插件,可以在babel官网查看
// babel的逻辑或赋值运算符插件
yarn add @babel/plugin-transform-logical-assignment-operators -D // or npm i -D @babel/plugin-proposal-optional-chaining
// babel的空值操作运算符插件
yarn add @babel/plugin-transform-nullish-coalescing-operator -D
// babel的可选链运算符插件
yarn add @babel/plugin-transform-optional-chaining -D
然后在babel.config.js中引入
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
],
plugins: [
'@babel/plugin-transform-logical-assignment-operators',
'@babel/plugin-transform-nullish-coalescing-operator',
'@babel/plugin-transform-optional-chaining'
]
}
tips:plugins中多个plugin也可以使用二维数组,在二维数组里配置plugin的配置项。
执行run build打包即可转义。
替换写法
如果不想改变打包的体积和安装依赖,我们可以重新替换写法。这些运算符本质上是语法糖。
比如:
逻辑或赋值运算符, 先逻辑或,如果是false,再赋值给变量。
name ||= '佚名'
// 等同于(name || name = '佚名')
空值操作运算符,只要value等于null或者undefined,就返回后面的值,否则返回value。
name ?? '佚名'
// 等同于(name != null ? name : '佚名')
// 等同于((name !== null && name !== void 0) ? name : '佚名')
可选链操作符,只要左边等于null或者undefined,就返回undefined,否则链式取右边的值。
a?.b
// 等同于(a == null ? undefined : a.b)
// 等同于((name === null || name === void 0) ? undefined : a.b)
选择
因为方案1可能打包的体积比之前大的多,对于方案3, 我们用的地方多,改起来还比较繁琐,而且使用新语法也挺好的。
我们最终采用了第二种方案,安装对应的依赖,打包,部署。
在safari浏览器打开,不会报错了,可以正常打开,算解决了。
这个问题排查和解决的过程,主要是排查过程费时,问题一旦排查出来,解决方案也就水到渠成了,希望对你们有帮助。