# 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 "\\(\\?