Polyfills

一、Babel Polyfill 与 core-js 概述

在现代前端开发中,我们使用 ES6+ 甚至 ES202x 的新语法和 API 编写代码,但为了兼容旧版浏览器(如 IE、老版本 Chrome/Firefox),需要引入 Polyfill(垫片) 来为这些环境“补充”缺失的原生方法。

core-js 是目前业界最主流、模块化程度最高的 JavaScript 标准库 polyfill,它支持从 ES3 到 ES202x+ 以及 Web 标准 API 的全面兼容,是 Babel 官方推荐的 polyfill 解决方案。

二、core-js 的安装与引入方式

1. 安装

目前 core-js 主要分为两个版本线:

  • core-js@3:当前稳定版,推荐使用。
  • core-js@2:已停止维护,仅用于老项目兼容。

在项目中安装 core-js@3:

1
2
3
npm install core-js@3 --save
# 或
yarn add core-js@3

2. 三种常见引入方式

方式一:全量引入(不推荐,体积过大)

直接在入口文件顶部引入所有 polyfill,会导致包体积剧增,仅适合快速原型验证:

1
2
3
// 入口文件(如 main.js / index.js)
import "core-js/stable"; // 稳定版 ES+ API
import "regenerator-runtime/runtime"; // 如果使用了 async/await

方式二:按需自动引入(推荐,结合 Babel)

通过 @babel/preset-envuseBuiltIns 配置,让 Babel 根据你的目标浏览器列表,自动在代码中插入需要的 polyfill。

步骤 1:安装依赖

1
npm install @babel/preset-env @babel/core babel-loader --save-dev

步骤 2:配置 babel.config.json.babelrc

1
2
3
4
5
6
7
8
9
10
11
12
{
"presets": [
[
"@babel/preset-env",
{
"targets": "> 0.25%, not dead", // 目标浏览器
"useBuiltIns": "usage", // 自动按需引入
"corejs": 3 // 指定 core-js 版本为 3
}
]
]
}
  • useBuiltIns: "usage":Babel 会分析你的代码,只在用到新 API 的文件中引入对应的 polyfill,最小化体积。

方式三:手动按需引入(极致体积控制)

如果你只想为特定的 API 打补丁,可以手动引入 core-js 下的对应模块:

1
2
3
// 例如只引入 Array.prototype.includes 和 Promise
import "core-js/stable/array/includes";
import "core-js/stable/promise";

三、Array 与 DOM API 的 Polyfill 示例

1. Array 系列

core-js 对 Array 提供了极其全面的支持,包括但不限于:

  • Array.from
  • Array.of
  • Array.prototype.find / findIndex
  • Array.prototype.includes
  • Array.prototype.flat / flatMap

通过上述“方式二(按需自动引入)”,当 Babel 检测到你使用了这些方法且目标浏览器不支持时,会自动注入对应的 polyfill,无需手动干预。

2. Element.getAttributeNames()

方法说明

Element.getAttributeNames() 是 DOM API,用于以字符串数组形式返回当前元素的所有属性名。配合 getAttribute() 使用,比直接访问 Element.attributes 更高效。

原生 Polyfill 实现(不依赖 core-js 时)

如果项目未引入 core-js,可使用以下代码手动兼容(主要针对 IE):

1
2
3
4
5
6
7
8
9
10
11
if (Element.prototype.getAttributeNames == undefined) {
Element.prototype.getAttributeNames = function () {
var attributes = this.attributes;
var length = attributes.length;
var result = new Array(length);
for (var i = 0; i < length; i++) {
result[i] = attributes[i].name;
}
return result;
};
}

浏览器兼容性

  • Chrome: 61+
  • Edge: 18+
  • Firefox: 45+
  • IE: 不支持
  • Safari: 10+

Polyfills
https://cszy.top/20230411-polyfills/
作者
csorz
发布于
2023年4月11日
许可协议