# Legacy 构建与兼容性指南(Vite 与 Webpack) 目的 - 当你遇到旧浏览器(例如低版本 iOS / Safari)导致页面白屏或运行时报错的兼容性问题时,应考虑两类方案: 1. 在源码层修复(首选,必要时必须做的,比如 RegExp 语法不可能被 polyfill) 2. 在构建/部署层使用 legacy 构建(为旧浏览器生成降级 bundle + polyfills) 重要提醒(核心) - 一些问题(例如使用正则 lookbehind `(?= 11'], additionalLegacyPolyfills: ['regenerator-runtime/runtime'], // modern polyfilled bundle + legacy (nomodule) bundle -> differential serving renderLegacyChunks: true, }) ] }) ``` - 解释与建议: - `targets` 使用浏览器目标来决定哪些语法/transform 需要降级;根据你需要支持的最低版本设置(例如 `iOS >= 11`)。 - `additionalLegacyPolyfills` 可以把某些运行时库插入 legacy bundle;但大多数 API polyfill(例如 `Promise` / `fetch`)应通过 `core-js` 或手动引入更精细地控制。 - `renderLegacyChunks: true` 会生成兼容旧浏览器的 chunk(按需 polyfill 注入),并配合 ` ``` - 注意事项: - 两套构建会增加构建复杂度与 CI 时间;但可以确保对旧浏览器的兼容性控制更粒度。 - 同样强调:如果源码中包含引擎级不支持的正则字面量(例如 lookbehind),在构建阶段仍可能失败或在旧浏览器上报错 —— 这些必须在源码层修复或用运行时延迟构造。 3) polyfills 管理建议 - 使用 `core-js`(v3)做标准 API polyfill,结合 Babel 的 `useBuiltIns: 'usage'` 自动注入,或手动在入口文件按需 `import 'core-js/stable'`。 - 对于 async/await:`regenerator-runtime/runtime`。 - 注意不要把不必要的 polyfill注入到 modern bundle;使用 differential serving(或 plugin-legacy)确保最小现代 bundle。 4) 正则(RegExp)与引擎级语法的特殊说明 - 正则语法(例如 lookbehind)是 JS 引擎实现的语言特性,无法用 runtime polyfill 修复。解决办法: - 在源码中改写为兼容写法(例如把 `(? scripts) ```json { "scripts": { "check:regex-advanced": "rg --hidden --glob '!node_modules' --glob '!dist' -n --glob '**/*.{js,ts,vue,jsx,tsx,mjs,cjs}' '\\(\\? 在构建中添加 legacy 支持 -> 在 CI/QA 上验证旧设备的真实表现 -> 在项目中加入静态检查以防回归。 附录:参考命令 ```bash # Vite 本地打包 (含 legacy) pnpm build # Webpack 两套构建 (示例) pnpm run build:modern pnpm run build:legacy # 静态检查(本地快速跑) pnpm dlx rg "\\(\\?