Next.js在iOS Safari中因导入Typescript enum导致白屏问题咨询
问题原因
该问题是TypeScript枚举跨monorepo包导出时,与iOS Safari的JS解析逻辑不兼容导致的静默执行失败,触发条件如下:
- 你的
shared公共包构建产物保留了export enum的原生ES导出格式,未转译为兼容的普通对象结构 - iOS Safari(尤其是15及更早版本)对跨模块的枚举导出存在解析Bug,遇到无法识别的枚举内容时不会抛出可见错误,直接中断后续页面渲染逻辑导致白屏
- 间接引用enum时,枚举仅作为TypeScript类型使用,编译阶段会被类型擦除,实际运行时不会加载enum的导出内容,因此不会触发问题;直接导入enum时运行时需要加载枚举值,就触发了Safari的解析Bug
解决方案
以下方案按改造成本从低到高排序,任选一种即可解决问题:
方案1:将shared包中所有
enum替换为as const常量对象,兼容原有使用逻辑// 替换前 export enum Protocol { ETHEREUM = 'ETHEREUM' } // 替换后,功能和类型提示完全和原有enum一致 export const Protocol = { ETHEREUM: 'ETHEREUM' } as const export type Protocol = typeof Protocol[keyof typeof Protocol]该方案不需要修改其他包的引用代码,改造成本最低。
方案2:调整shared包的构建配置,将枚举转译为ES5兼容格式
如果你用tsc直接编译shared包,将tsconfig.json中的target字段改为ES5即可。
如果你用tsup构建shared包,添加如下配置即可:// tsup.config.ts export default { target: 'es5', esbuildOptions(options) { options.supported = { 'enum': false } } }方案3:修改导入路径,绕开根目录批量导出的解析问题
把直接从shared根目录导入的写法:import { Protocol } from '@*/shared'改为指定完整枚举文件路径导入:
import { Protocol } from '@*/shared/enums/Protocol'
内容的提问来源于stack exchange,提问作者user9886507
相关产品推荐
相关产品推荐

