Angular项目IOS16.1.1设备页面空白问题
IOS设备适配
- 问题与经历
- 结语
问题与经历
最近遇到一个IOS16.1.1系统访问H5页面空白的问题,一开始MAC上Safari调试时发现main.js报错unexpected token ‘{’, 看似是对ES6特性不支持;故尝试降级成ES5,发现依旧无法访问。
但是由于项目有两个工程,一个是由Angular写的,一个是由Vue写的,其中Angular项目的页面IOS访问不了,而Vue项目的页面却可以访问,于是开始对比两个页面的main.js,发现Angular中有use strict,而Vue中没有,于是产生了去除Angular中严格模式的想法,但咨询后发现尽量不要这样去修改,导致方向又断了。
后面一天,那晚迷迷糊糊做了个梦,梦到有高人指点,解决了这个问题,结果没想到的是第二天,真有高人指点,说可能是browerlist的问题。
于是检查了两个项目的browerlist,Angular如下:
and_chr 137
and_ff 139
and_qq 14.9
and_uc 15.5
android 137
chrome 137
chrome 136
chrome 135
chrome 134
chrome 131
chrome 109
edge 137
edge 136
edge 135
firefox 139
firefox 138
firefox 128
ios_saf 18.5
ios_saf 18.4
ios_saf 18.3
ios_saf 17.6-17.7
ios_saf 16.6-16.7
kaios 3.0-3.1
kaios 2.5
op_mini all
op_mob 80
opera 117
opera 116
safari 18.5
safari 18.4
samsung 28
samsung 27
而Vue项目的browerlist如下:
and_chr 138
and_ff 140
and_qq 14.9
and_uc 15.5
android 138
chrome 138
chrome 137
chrome 136
chrome 131
chrome 112
chrome 109
edge 138
edge 137
edge 136
firefox 140
firefox 139
firefox 128
ios_saf 18.5
ios_saf 18.4
ios_saf 18.3
ios_saf 17.6-17.7
ios_saf 16.6-16.7
kaios 3.0-3.1
kaios 2.5
op_mini all
op_mob 80
opera 117
opera 116
safari 18.5
safari 18.4
samsung 28
samsung 27
可以看到其实两个项目都只支持IOS16.6 和 16.7,这个时候我去询问发现出问题的设备系统为IOS16.1.1。于是可以下判断大概率是这里出了问题。于是修改了Angular项目的browerlist支持IOS16以上的系统,终于设备中页面可以看到了,此时悬着的心终于是亖了。
不过还有一个问题是,为什么Vue项目也是相同配置,但是却能够显示页面呢。这询问了AI后回答是
与 Vue 工程有相同的覆盖不全问题,但 Angular 的构建链更容易因此崩溃
与 Vue 工程的差异对比:
特性 | Angular | Vue | 对 iOS 16 的影响 |
---|---|---|---|
构建工具 | Webpack | Vite | Webpack 的转译策略更保守 |
模块系统 | UMD/IIFE | 原生 ESM | iOS 16 对 ESM 支持更好 |
Polyfill 注入 | 手动 (polyfills.ts) | 自动 (plugin-legacy) | Angular 更容易遗漏必要补丁 |
语法转译策略 | Webpack 保守转译 + @angular-devkit | Vite 默认使用现代模式 + @vitejs/plugin-legacy | Vue 对未声明版本会降级到 ES2015,而 Angular 可能因配置冲突生成不兼容代码 |
关键结论:是否由 browserslist 直接导致?
-
直接原因:否
两者配置几乎相同(均漏配 iOS 16.0-16.5),但仅 Angular 崩溃,说明 根本问题不在 browserslist 本身Vue 能正常运行得益于:
Vite 的现代模式 对未声明版本有更安全的降级策略
ESM 原生支持 比 Webpack 的 IIFE 更兼容 iOS 的严格模式
-
间接原因:是
browserslist 的 漏配放大了 Angular 构建链的弱点:Webpack 在无明确版本指令时,默认生成 更高版本的 ES 语法(如箭头函数)
Angular 的 Zone.js 对执行环境更敏感(依赖 globalThis 等新 API)
因此可以肯定browserslist 配置缺陷导致的是Angular CLI 认为不需要为 iOS 16.1.1 降级语法,生成 ES2015+ 代码(如箭头函数、class)。
结语
说来也好笑,其实Angular里的browerlist是copy来的:
> 0.5%
last 2 versions
Firefox ESR
not dead
not IE 9-11 # For IE 9-11 support, remove 'not'.
而Vue是通过编译配置解决的,因为Angular项目没办法那么配,虽然最后生成的browerlist没什么区别,但是却导致了这种乌龙事件。