preset-env
一、认识
旧版浏览器的语法兼容问题主要分两类: 语法降级问题和 Polyfill
缺失问题。前者比较好理解,比如某些浏览器不支持箭头函数,我们就需要将其转换为 function(){}
语法;而对后者来说,Polyfill
本身可以翻译为垫片,也就是为浏览器提前注入一些 API
的实现代码,如 Object.entries
方法的实现,这样可以保证产物可以正常使用这些 API
,防止报错。
这两类问题本质上是通过前端的编译工具链(如Babel
)及 JS
的基础 Polyfill
库(如corejs
)来解决的,不会跟具体的构建工具所绑定。
1.1 useBuiltIns: entry
useBuiltIns: entry
声明 Polyfill
策略为 entry
, entry
配置规定你必须在入口文件手动添加一行这样的代码:
import 'core-js';
Babel
所做的事情就是将你的 import "core-js"
代码替换成了产物中的这些具体模块的导入代码。这个配置有一个问题,即无法做到按需导入,上面的产物代码其实有大部分的 Polyfill
的代码我们并没有用到。
1.2 useBuiltIns: usage
useBuiltIns: usage
真正地实现了按需 Polyfill
导入
1.3 preset-env polyfill
利用 @babel/preset-env
进行了 目标浏览器语法的降级 和 Polyfill
注入,同时用到了 core-js
和regenerator-runtime
两个核心的运行时库。但 @babel/preset-env
的方案也存在一定局限性:
-
如果使用新特性,往往是通过基础库(如
core-js
)往全局环境添加Polyfill
,如果是开发应用没有任何问题,如果是开发第三方工具库,则很可能会对全局空间造成污染。 -
很多工具函数的实现代码(如上面示例中的
_defineProperty
方法),会在许多文件中重现出现,造成文件体积冗余。
二、安装
安装必要编译时依赖:
pnpm install @babel/cli @babel/core @babel/preset-env -D
-
@babel/cli
: 为babel
官方的脚手架工具 -
@babel/core
:babel
核心编译库。 -
@babel/preset-env
:babel
的预设工具集,基本为babel
必装的库。
安装必要运行时依赖: Polyfill
代码主要来自 core-js
和 regenerator-runtime
,因此如果要运行起来,必须要装这两个库。
pnpm i core-js regenerator-runtime -S
-
core-js
-
regenerator-runtime
三、配置
3.1 .browserslistrc
Browserslist
是一个帮助我们设置目标浏览器的工具,不光是 Babel
用到,其他的编译工具如postcss-preset-env
、autoprefix
中都有所应用。对于 Browserslist
的配置内容,你既可以放到 Babel
这种特定工具当中,也可以在package.json
中通过browserslist
声明:
ie >= 11
3.2 babel.config.js
useBuiltIns: "entry"
export default {
presets: [
[
'@babel/preset-env',
{
corejs: 3,
modules: false,
useBuiltIns: "entry"
}
]
],
};
useBuiltIns: "usage"
export default {
presets: [
[
'@babel/preset-env',
{
corejs: 3,
modules: false,
useBuiltIns: "usage"
}
]
],
};
四、测试
4.1 index.js
// 如果 useBuiltIns: "entry" , 需要引入 import "core-js"
const func = async ()=>{
console.log("Hello World!")
}
func();
Promise.resolve().finally();
4.2 命令行输入
npx babel ./index.js --out-dir dist
使用 Babel
进行编译
效果如下: