iOS 10出现白屏幕,其他机型不会。

一个bug

手机连上电脑,在电脑端的​​Safari​​里,看到了如下的错误:

SyntaxError: Cannot declare a let variable twice: 'e'.

可是你没有写过这样的代码,你怎么可能把一个名为​​e​​的变量定义两次?你打开代码,看到了这样美丽的代码: 

let e = e => {
console.log(e);
for (let e of [1, 2, 3])
console.log(e);
};

况且很显然,这段代码不是人写的,而是我们在执行​​npm run build​​的时候编译产生的。

其实我们都没有错,我们也没写错,​​uglify​​​也没搞错,错的是​​Safari​​本身。他们在第十七万一千零四十一号bug中承认了自己的错误:

(We incorrectly throw a syntax error when declaring a top level for-loop iteration variable the same as a parameter

当你定义一个与参数同名的for循环迭代变量时,我们错误地认为这是一个语法错误。)


  1. 进入​​build​​文件夹;
  2. 找到​​webpack.prod.conf.js​​文件;
  3. 在​​UglifyPlugin​​的定义里添加关于​​mangle​​的选项,使它变成下面这个样子:
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false
},
mangle: {
safari10: true
}
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),

其实我们建议​​Vue​​​官方在​​vue-cli​​工具里缺省加入这个选项,以避免大家的麻烦。

另一个bug

还有另外一个bug也会影响到vue网页在iOS 10上的展现,特别是当你用到广为流传的Swiper插件的时候。这是因为Swiper插件中用到了ES6的语法a = b c,a是b的c次方,而iOS 10的Safari里不认识这样的语法,认为这是一个错误,所以你需要让Swiper经过babel的包装,而缺省状态下babel是不对node_modules里的模块进行编译的。相关的issue见这里。

解决方法是在项目根目录下新建一个文件vue.config.js,在里面添加如下语句:

module.exports = {
chainWebpack: config => {
config.rule('js').include.add(/node_modules\/(dom7|swiper)\/.*/)
}
}