一组 Babel 插件,可以在编译的代码中使用不同的策略注入不同的 polyfill。此外,该存储库还包含一个包,可帮助为其他 Polyfill 创建提供程序。
该存储库实现了 babel/babel#10008 最初提出的内容。
如果您正在寻找一些快速设置示例,或者只是想了解如何迁移您的配置,请查看
docs/migration.md
。
主要的 Babel 包仅转换 JavaScript语法:您还需要加载一个 polyfill,以使本机函数( Array.prototype.flat
) 或内置对象( Reflect
) 在旧浏览器中工作。
最简单的方法是使用标签直接加载 polyfill:
< script src =" https://unpkg.com/[email protected]/minified.js " > script >
然而,这种简单的方法可能会包含大量不必要的代码。在此存储库中实现的 Babel 插件会自动将填充代码注入到您的代码中,同时尝试仅加载真正需要的内容。它根据您的编译目标和您在代码中使用的内容来执行此操作。
这些插件(我们称之为“polyfill 提供程序”)支持不同的注入方法,以更好地满足您的需求。
例如,如果你想通过将缺少的函数添加到全局对象来将导入注入到es-shims
polyfills,你可以这样配置 Babel:
配置 | 输入代码 | 输出代码 |
---|---|---|
{
"targets" : { "firefox" : 65 },
"plugins" : [
[ " polyfill-es-shims " , {
"method" : " usage-global "
}]
]
}
| Promise . allSettled ( [
p1 ,
p2
] ) . finally ( ( ) => {
console . log ( "Done!" ) ;
} ) ; | {
console.log("Done!");
});"> import "promise.prototype.finally/auto" ; import "promise.allsettled/auto" ; Promise . allSettled ( [ p1 , p2 ] ) . finally ( ( ) => { console . log ( "Done!" ) ; } ) ; |
如果您想查看更多配置示例,可以查看迁移文档: docs/migration.md
。
如果您有兴趣阅读这些插件支持的所有选项,您可以查看使用文档: docs/usage.md
。
聚合物填料 | 插件 | 方法 |
---|---|---|
core-js@2 | babel-plugin-polyfill-corejs2 | entry-global 、 usage-global 和usage-pure |
core-js@3 | babel-plugin-polyfill-corejs3 | entry-global 、 usage-global 和usage-pure |
es-shims | babel-plugin-polyfill-es-shims | usage-global 和usage-pure |
regenerator-runtime | babel-plugin-polyfill-regenerator | entry-global 、 usage-global 和usage-pure |
我们将维持对
core-js
和es-shims
的支持,但我们鼓励您为您自己的 polyfill 或您最喜欢的polyfill 实现一个提供程序!我们的目标之一是鼓励不同的 Polyfill 之间的竞争,以更好地平衡规范合规性和代码大小等不同的权衡。如果你想实现对自定义 polyfill 的支持,可以使用
@babel/helper-define-polyfill-provider
。 (docs/polyfill-provider.md
。)
Polyfill 插件可以公开三种不同的注入方法: entry-global
、 usage-global
和usage-pure
。请注意,polyfill 插件不会自动将必要的包添加到您的依赖项中,因此您必须在package.json
中显式列出它们。
所有示例均假设您的目标平台是 Chrome 62。
entry-global
方法用对目标环境不支持的特定功能的导入来替换对整个polyfill的单个简单导入。当您想要确保每个不支持的函数都可用时,无论您在使用 Babel 编译的代码中使用什么,它都是最有用的。如果出现以下情况,您可能需要使用此方法:
输入代码 | 输出代码 |
---|---|
import "core-js" ; | import "core-js/modules/es7.array.flat-map.js" ;
import "core-js/modules/es6.array.sort.js" ;
import "core-js/modules/es7.promise.finally.js" ;
import "core-js/modules/es7.symbol.async-iterator.js" ;
import "core-js/modules/es7.string.trim-left.js" ;
import "core-js/modules/es7.string.trim-right.js" ;
import "core-js/modules/web.timers.js" ;
import "core-js/modules/web.immediate.js" ;
import "core-js/modules/web.dom.iterable.js" ; |
usage-global
方法将导入注入附加到全局范围的 polyfill,但仅限于代码中使用的不受支持的功能。如果出现以下情况,您可能需要使用此方法:
输入代码 | 输出代码 |
---|---|
foo . flatMap ( x => [ x , x + 1 ] ) ;
bar . trimLeft ( ) ;
arr . includes ( 2 ) ; | [x, x + 1]);
bar.trimLeft();
arr.includes(2);"> import "core-js/modules/es.array.flat-map.js" ; import "core-js/modules/es.array.unscopables.flat-map.js" ; import "core-js/modules/es.string.trim-start.js" ; foo . flatMap ( x => [ x , x + 1 ] ) ; bar . trimLeft ( ) ; arr . includes ( 2 ) ; |
usage-pure
方法将导入注入到代码中使用的不受支持的功能的 polyfill 中,而不将 polyfill 附加到全局范围,而是将它们作为普通函数导入。如果出现以下情况,您可能需要使用此方法:
输入代码 | 输出代码 |
---|---|
foo . flatMap ( x => [ x , x + 1 ] ) ;
bar . trimLeft ( ) ;
arr . includes ( 2 ) ; | [x, x + 1]);
_trimLeftInstanceProperty(bar).call(bar);
arr.includes(2);"> import _flatMapInstanceProperty from "core-js-pure/stable/instance/flat-map.js" ; import _trimLeftInstanceProperty from "core-js-pure/stable/instance/trim-left.js" ; _flatMapInstanceProperty ( foo ) . call ( foo , x => [ x , x + 1 ] ) ; _trimLeftInstanceProperty ( bar ) . call ( bar ) ; arr . includes ( 2 ) ; |
在过去的三年半中, @babel/preset-env
展示了其在减少包大小方面的全部潜力,不仅不转译支持的语法功能,而且不包含不必要的core-js
polyfill。
到目前为止,Babel 提供了三种不同的方式在源代码中注入core-js
polyfill:
@babel/preset-env
的useBuiltIns: "entry"
选项,可以为目标浏览器本身不支持的每个 ECMAScript 功能注入自安装的 polyfill;@babel/preset-env
的useBuiltIns: "usage"
,Babel 只会为不支持的 ECMAScript 功能注入自安装的 polyfill,但前提是它们实际在输入源代码中使用;@babel/plugin-transform-runtime
,Babel 将为core-js
支持的每个使用的 ECMAScript 功能注入“纯”polyfill(与自安装的不同,它不会污染全局范围)。这通常由库作者使用。我们的旧方法有两个主要问题:
@babel/preset-env
的targets
选项与“纯”polyfills 一起使用,因为@babel/plugin-transform-runtime
是一个完全独立的包。core-js
。 core-js
是一个优秀且全面的 polyfill,但它并不能满足我们所有用户的需求。通过这个新的软件包,我们提出了解决这两个问题的方案,同时仍然保持完全的向后兼容性。
请参阅我们的 CONTRIBUTING.md 以开始设置存储库。