vite 增加 polyfill 配置

Polyfill 的含义

基本定义

Polyfill(填充物)是一段代码,用于在旧浏览器中实现新浏览器才有的功能。它让旧浏览器也能使用新的 JavaScript API 或语法特性。

名称来源

  • Poly = 多种/多个
  • Fill = 填充

意思是"用代码填充缺失的功能"。

工作原理

当浏览器不支持某个 API 时,polyfill 会:

  1. 检测浏览器是否支持该功能
  1. 如果不支持,用旧 API 或兼容方式实现相同功能
  2. 让代码在旧浏览器中也能正常运行

vite 项目配置

1. package.json 配置 browserslist

因为我开发的,是 h5 的 C 端项目,所以配置如下,具体的兼容浏览器列表要根据实际情况定

json 复制代码
"browserslist": [
    "> 0.5%",
    "last 2 versions",
    "iOS >= 10",
    "Android >= 5",
    "not dead",
    "not ie 11",
    "not op_mini all"
  ]

配置项说明:

  • "> 0.5%"(市场占有率):支持全球市场份额 > 0.5% 的浏览器,覆盖主流浏览器
  • "last 2 versions"(最新版本):支持每个浏览器的最新 2 个版本,例如:Chrome 最新版和上一个版本
  • "iOS >= 10"(iOS Safari):支持 iOS 10 及以上的 Safari,覆盖 iPhone/iPad 的常见版本
  • "Android >= 5"(Android):支持 Android 5.0(Lollipop)及以上,覆盖大部分 Android 设备
  • "not dead"(排除已停止维护):排除已停止维护的浏览器,例如:IE 10 及以下、旧版 Opera
  • "not ie 11"(排除 IE 11):明确排除 IE 11
  • "not op_mini all"(排除 Opera Mini):排除所有版本的 Opera Mini,Opera Mini 功能受限,通常不支持现代特性

2. 安装依赖

@vitejs/plugin-legacy:兼容 Vite 5

terser:用于压缩 legacy 构建产物

perl 复制代码
npm install --save-dev "@vitejs/plugin-legacy@^5.4.0" terser

3. 配置 Vite

在 vite.config.js 中,插件会自动读取 package.json 中的 browserslist 配置

javascript 复制代码
import legacy from '@vitejs/plugin-legacy';
export default defineConfig(({ mode }) => ({
    plugins: [
        vue(),
        createHtmlPlugin({ inject: { data: { ...conf } } }),
        legacy({
            // 自动读取 package.json 中的 browserslist 配置
            modernPolyfills: true,
            renderLegacyChunks: true
        })
    ],
  // ......
}

babel.config.js无需调整,因为 @vitejs/plugin-legacy 会自动处理 polyfill。

browserslist 与 Legacy 代码的关系

工作原理

browserslist 定义的是"目标浏览器范围"(需要支持的浏览器)。@vitejs/plugin-legacy 的工作流程:

构建时:

  • 根据 browserslist 生成两套代码:
  • 现代版本(modern):ES6+ 语法,给新浏览器
  • Legacy 版本(legacy):转译后的 ES5 代码 + polyfill,给旧浏览器

运行时(浏览器访问时):

  • 通过特性检测(feature detection)判断浏览器能力
  • 支持现代特性的浏览器 → 加载现代版本
  • 不支持现代特性的浏览器 → 加载 Legacy 版本

运行时检测机制:

@vitejs/plugin-legacy 会在 HTML 中注入类似这样的代码:

xml 复制代码
<script type="module" src="modern.js"></script>
<script nomodule src="legacy.js"></script>
  • 支持 ES modules 的浏览器 → 加载 modern.js
  • 不支持 ES modules 的浏览器 → 加载 legacy.js(包含 polyfill)

举例说明

假设配置是:

json 复制代码
"browserslist": [
   "> 0.5%",
   "iOS >= 10",
   "Android >= 5"
]

不同浏览器的处理:

浏览器类型 是否在 browserslist 内 实际加载的代码
iOS Safari 12(新) ✅ 在范围内 现代版本(modern)
iOS Safari 10(旧) ✅ 在范围内 Legacy 版本(legacy + polyfill)
iOS Safari 9(更旧) ❌ 不在范围内 Legacy 版本(可能不完整,可能报错)
Chrome 120(最新) ✅ 在范围内 现代版本(modern)
Chrome 50(旧) ✅ 在范围内 Legacy 版本(legacy + polyfill)
IE 11 ❌ 被排除 不加载(配置了 not ie 11)

总结

  • browserslist 是"最低支持标准"
  • 在范围内的旧浏览器 → 会加载 legacy 代码
  • 在范围内的新浏览器 → 会加载现代代码(性能更好)
  • 不在范围内的更旧浏览器 → 可能加载 legacy,但不保证完全兼容
  • 被明确排除的浏览器(如 not ie 11)→ 不生成支持代码
相关推荐
风月说与山鬼1 小时前
三、大括号语法
前端·react.js
kyriewen1 小时前
我把最常踩的8个CORS跨域报错整理了一遍——第8个去年还不存在
前端·javascript
Csvn2 小时前
🕰️ 闭包 + setTimeout 的 5 个经典陷阱:为什么定时器看到的永远不是最新的值?
前端
lilian2332 小时前
Harmony os 技术实战|拼豆制图27:用单字符编码承载 50 张 70×70 图纸
前端·数据库·华为·harmonyos
CarIise3 小时前
CSS选择器与样式关联
前端·css·tensorflow
里欧跑得慢4 小时前
CSS 模块化架构的演进:BEM、CSS Modules 到 CSS-in-JS 的反思
前端·css·flutter·web·css-in-js
IT_陈寒4 小时前
Vue的computed属性把我坑惨了,原来我一直用错姿势
前端·人工智能·后端
小灰灰搞电子5 小时前
Rust+Slint 实现温度计源码分享
前端·rust·slint
计算机魔术师5 小时前
面壁智能 OpenBMB 推出 MathForm,面向 Lean 4 数学自动形式化的开源框架、数据集与模型
前端