core-js放弃开源!细数前端10+百万级热门 Polyfill!

家好,很高兴又见面了,我是"高级前端 进阶 ",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!

高级前端 进阶

前不久关于core-js作者的事情在科技圈闹得沸沸扬扬,具体可以阅读我的文章《前端地震!core-js作者放弃开源?》,今天将带着大家一起细数前端周均下载百万、甚至千万级别的Polyfill。话不多说,直接开始!

什么是polyfill?

polyfill 是通过修补 API 来添加缺失功能的代码,典型的例子是通过polyfill在旧浏览器中添加新功能。 例如,Modernizr 检测浏览器功能并使用一组 polyfill 来启用旧浏览器中的浏览器功能,或者提供尚不支持的功能的补丁。

下面代码是笔者用于处理Android 4.4以下浏览器webview不支持部分功能的代码,分别添加了url-polyfill(可以使用new URL)、babel-polyfill、es5-shim(部分代码兼容)这3个polyfill:






这种解决方案的问题是:因为它们是修补缺失的API方法,所以特点是污染全局作用域。至于如何解决,以前写过一篇文章《前端 Polyfill、Ponyfill、Prollyfill 傻傻分不清楚?》单独论述过,本文将重点关注在前端的热门polyfill上。

core-js

什么是core-js?

Core-js是JavaScript 的模块化标准库。 包括 ECMAScript 的 Polyfill 到 ES2023,主要囊括:Promise、Symbol、Collections、 Iterators、 Typed Arrays,、类型数组以及诸多其他特性、ECMAScript 提案、一些跨平台的 WHATWG/W3C 特性和提案等等。

将上面的简短介绍拆开来看,主要包括以下核心特性

比如通过如下方式引入core-js将不会污染全局变量:

import Promise from 'core-js-pure/actual/promise';
import Set from 'core-js-pure/actual/set';
import Iterator from 'core-js-pure/actual/iterator';
import from from 'core-js-pure/actual/array/from';
import flatMap from 'core-js-pure/actual/array/flat-map';
import structuredClone from 'core-js-pure/actual/structured-clone';
Promise.resolve(42).then(it => console.log(it)); 
// => 42
from(new Set([1, 2, 3]).union(new Set([3, 4, 5]))); 
// => [1, 2, 3, 4, 5]
flatMap([1, 2], it => [it, it]); 
// => [1, 1, 2, 2]
Iterator.from(function * (i) { while (true) yield i++; }(1))
  .drop(1).take(5)
  .filter(it => it % 2)
  .map(it => it ** 2)
  .toArray(); 
// => [9, 25]
structuredClone(new Set([1, 2, 3])); 
// => new Set([1, 2, 3])

目前Core-js的NPM周下载量稳定在34138K,Github上star超过21.7K,fork达到了1.6K,有超过13,642K的项目使用它,超过115+代码贡献者。

es5-shim

es5-shim.js 和 es5-shim.min.js 用来为 JavaScript 上下文打补丁以包含所有 EcmaScript 5 方法,这些方法可以用遗留 JavaScript 引擎模拟。 注意:由于 es5-shim.js 是为了给原生 Javascript 引擎打补丁,所以它应该是最先加载的库。

Array.prototype.every (standalone shim)
Array.prototype.filter (standalone shim)
Array.prototype.forEach (standalone shim)
Array.prototype.indexOf (standalone shim)
// 更多数组方法
Date.now
Date.prototype.toJSON
// 更多Date方法
Number.prototype.toExponential (standalone shim)
Number.prototype.toFixed
Number.prototype.toPrecision
// 更多Number方法
String.prototype.split (standalone shim)
String.prototype.trim (standalone shim)
String.prototype.lastIndexOf (standalone shim)
String.prototype.replace
// 更多String方法
Error.prototype.toString
Error.prototype.name
Error.prototype.message
// 更多Error方法

es5-sham.js 和 es5-sham.min.js 为 其他 ES5 方法打补丁,比如:

Object.create
Object.getPrototypeOf
Object.getOwnPropertyNames
Object.isSealed
Object.isFrozen
Object.isExtensible
Object.getOwnPropertyDescriptor
Object.defineProperty
// 更多其他方法

目的是为了允许将代码写入 ES5 而不会在旧引擎中导致运行时错误。 在许多情况下,这意味着这些打补丁的方法会导致许多 ES5 方法在低版本浏览器上默默地执行失败。 同时需要注意的是:es5-sham.js 需要 es5-shim.js 才能正常工作。

在浏览器项目中使用 ES 兼容性垫片的示例代码如下:






目前es5-shim的NPM周下载量稳定在3443K,Github上star超过7.1K,fork达到了1K。

@babel/polyfill

Babel 默认只转换新的 JavaScript 句法,例如箭头函数、扩展运算符等,而不会转换新的 API,像是Set、Maps、Iterator、Generator 、Symbol、Reflect 等全局对象,以及一些定义在全局对象上的方法都不会进行转译。如果想使用这些新的对象和方法,则需要为当前环境提供一个 polyfill 垫片。

例如: ES6 在 Array 对象上有一个新增的 Array.from 方法,因为这个方法是全局对象上的方法,所以 Babel 就不会对这个方法进行转译。如果想让这个方法运行,就要使用 @babel/polyfill 为当前环境提供一个垫片。

需要首先安装:

npm install --save @babel/polyfil

安装好后就可以在程序入口文件的顶部引用 @babel/polyfil::

import '@babel/polyfill'
[].findIndex('babel')

babel-polyfill 解决了 Babel 不转换新 API 的问题,但是直接在代码中插入帮助函数,会导致污染了全局环境,并且不同的代码文件中包含重复的代码,导致编译后的代码体积变大。虽然这对于应用程序或命令行工具来说可能是好事,但如果已有代码打算提供给其他人使用的库,可能会有问题。

需要注意的是从 Babel 7.4.0 开始,不再推荐使用 @babel/polyfill 包,而是直接使用 core-js/stable 和 regenerator-runtime/runtime,如下所示:

import "core-js/stable";
import "regenerator-runtime/runtime";

目前@babel/polyfil的NPM周下载量稳定在1572K,Github上star超过42K,fork达到了5.6K,有超过8K的项目使用它。

es6-promise-polyfill

这是 ES6 Promise 的 polyfill,该实现基于 Jake Archibald 实现的 rsvp.js 子集。这个库的主要目标是:Promise实现应该与浏览器的原生实现保持一致,并且尽可能小。 所以它只是 ES6 Promise 规范的严格 polyfill,仅此而已。

它通过了 Promises/A+ 测试套件和 rsvp.js 测试套件,体积最小 2.6KB( 1KB+gzip)。默认使用setImmediate(如果可用),或者回退使用 setTimeout。

const Promise = require('es6-promise-polyfill').Promise;
const promise = new Promise(...);

或者使用CDN方式加载:


目前es6-promise-polyfill的NPM周下载量稳定在32K。

es6-promise

这是 ES6 Promise 的 polyfill,实现是由 @jakearchibald 提取的 rsvp.js 的一个子集。使用这个库很简单,可以通过CDN的方式引入:



 
 


 
 

或者直接使用模块化方法:

const Promise = require('es6-promise').Promise;

如果要填充全局环境(在 Node 中或通过 CommonJS 在浏览器中),请使用以下代码片段:

require('es6-promise').polyfill();
// 或者
require('es6-promise/auto');

请注意,上面代码没有将 polyfill() 的结果分配给任何变量, polyfill() 方法将在调用时自动修补全局环境(在本例中为 Promise 名称)。

目前es6-promise的NPM周下载量稳定在8000K,Github上star超过7.3K,fork达到了637+,有超过3008K的项目使用它。

promise-polyfill

用于浏览器和Node环境的轻量级 ES6 Promise polyfill, 严格遵守浏览器规范。 它是一个完美的 polyfill IE 或任何其他不支持原生Promise的浏览器。同时,promise-polyfill非常轻巧,压缩后 < 1kb 。

可以通过CDN方式引用:

以上代码执行时候,如果浏览器没有 window.Promise,将会自动设置一个全局 Promise 对象。如果本机 Promise 不存在时候,想添加一个全局 Promise 对象(Node或浏览器),也可以使用如下模块化方法:

import 'promise-polyfill/src/polyfill';

如果不想影响全局环境(有时称为 ponyfill),可以导入基本模块。

import Promise from 'promise-polyfill';

默认情况下,promise-polyfill 使用 setImmediate,如果不支持这个方法,则回退到 setTimeout 以异步执行。 因此,如果浏览器不支持 setImmediate(IE/Edge 是唯一支持 setImmediate 的浏览器),您可能会遇到性能问题。但是,可以使用 setImmediate polyfill 来解决这个问题。

import Promise from 'promise-polyfill/src/polyfill';
import setAsap from 'setasap';
Promise._immediateFn = setAsap;

目前promise-polyfill的NPM周下载量稳定在2338K,Github上star超过2.1K,fork达到了300+,有超过756K的项目使用它。

promise

这是 Promises 的简单实现,它是一组 ES6 Promises 的超集,旨在提供可读、高性能的代码,并仅提供当今使用 promises 绝对必要的扩展。

注意:Promise通过下划线 (_) 前缀属性公开内部结构。

可以通过CDN方式引用:


//请注意,es5-shim 必须在此库之前加载,以支持 IE9 之前的浏览器。

或者也可以使用模块方法:

const Promise = require('promise');
const promise = new Promise(function (resolve, reject) {
  get('http://www.google.com', function (err, res) {
    if (err) reject(err);
    else resolve(res);
  });
});

promise库本身提供了诸如:Promise.resolve、Promise.reject、Promise.all、Promise.any、Promise.allSettled、Promise.denodeify、Promise.race等常见方法。比如下面是Promise.all的使用示例:

Promise.all([Promise.resolve('a'), 'b', Promise.resolve('c')])
  .then(function (res) {
    assert(res[0] === 'a')
    assert(res[1] === 'b')
    assert(res[2] === 'c')
  })

目前promise的NPM周下载量稳定在11704K,Github上star超过2.5K,fork达到了310+,有超过9560K的项目使用它。

url-search-params-polyfill

这是 JavaScript 的 URLSearchParams 类的 polyfill 库。具有以下明显特征:

可以通过如下方式导入使用:

import 'url-search-params-polyfill';
// Babel 和 ES2015+
require('url-search-params-polyfill');
//es5导入

开发者可以从字符串或对象实例化 URLSearchParams 的实例:

// new an empty object
var search1 = new URLSearchParams();
// from a string
var search2 = new URLSearchParams("id=1&from=home");
// from an object
var search3 = new URLSearchParams({ id: 1, from: "home" });
// from location.search, will remove first "?" automatically
var search4 = new URLSearchParams(window.location.search);
// from anther URLSearchParams object
var search5 = new URLSearchParams(search2);
// from a sequence
var search6 = new URLSearchParams([["foo", 1], ["bar", 2]]);

然后调用append、delete、get、getAll、has、set、toString、sort、forEach、keys、values、for..of等方法对URLSearchParams进行更改。

url-polyfill

Polyfill URL类 和 URLSearchParams类 以匹配最新的 WHATWG 规范。这个库在大多数用例中保持兼容,但不是 100%(如 unicode 字符、punycode 等),支持 IE 10+ 以上环境。

可以通过如下方式安装:

npm i url-polyfill --save

安装后即可在代码中直接使用:

const url = new URL('https://www.example.com/?fr=yset_ie_syc_oracle&type=orcl_hpset#page0');
url.searchParams.append('page', 0);
console.log(url.toString()); // print: "https://www.example.com/?fr=yset_ie_syc_oracle&type=orcl_hpset&page=0#page0"

目前url-polyfill的NPM周下载量稳定在285K,Github上star超过300+,fork达到了60+。

util.promisify

Node版本 < v8 的 util.promisify 的 Polyfill,但是Node v8.0.0 已经添加了对内置 util.promisify 的支持,无需再使用这个库。

可以直接使用:

const promisify = require('util.promisify');
// Use `promisify` just like the built-in method on `util`

或者shim方式引入:

require('util.promisify/shim')();
// `util.promisify` is now defined
const util = require('util');
// Use `util.promisify`

这个包需要一个原生的 ES5 环境,并且 Promise 在全局范围内可用,否则会抛出错误。目前util.promisify的NPM周下载量稳定在13756K。

本文总结

本文主要和大家介绍 Polyfill是什么,前端最火的10大Polyfill,以及如何使用。因为篇幅有限,文章并没有就每一个Polyfill过多展开,如果有兴趣,可以直接在我主页继续阅读,但是文末的参考资料提供了大量优秀文档以供学习。最后,欢迎大家点赞、评论、转发、收藏!


参考资料

https://www.npmjs.com/package/core-js

https://www.npmjs.com/package/es5-shim

https://www.npmjs.com/package/babel-polyfill

https://www.npmjs.com/package/es6-promise

https://www.npmjs.com/package/promise-polyfill

https://www.npmjs.com/package/promise

https://www.npmjs.com/package/url-search-params-polyfill

https://www.npmjs.com/package/url-polyfill

https://www.npmjs.com/package/util.promisify

https://www.npmjs.com/package/es6-promise-polyfill

展开阅读全文

页面更新:2024-03-24

标签:下载量   全局   浏览器   对象   稳定   热门   代码   方式   功能   环境   方法

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top