该如何配置 babel
配置方式一 entry
1、这种方式将 polyfill API 挂载到 window 上,或者挂载到原型上。
2、提供所有 targets 不支持的 api。体积可能稍微有点大。(不过不用那么在意)
3、不用担心目标环境不识别第三方库的代码里用到新语法。
在入口文件中导入 core-js
js
// main.js
import "core-js/stable";babel.config.js
js
module.exports = {
presets: [
[
// 需要下载依赖 @babel/preset-env
'@babel/preset-env',
{
// modules 设置为 false 后,编译产生的辅助函数会以 esm 方式导入
// 这样有利于打包工具比如 webpack 静态分析,进行 treeshaking 减少代码体积。
modules: false,
// 设置代码需要兼容目标环境
// 如果为空对对象,则代表兼容最古老的浏览器
// 查找 targets 配置的顺序为
// 1、preset-env 下的 targets
// 2、babel 配置文件的 targets
// 3、package.json 中的 browserslist
// 4、项目根目录下的 browserslist
targets: {},
// useBuiltIns 为 usage 时,corejs 才能设置为对象形式
corejs: '3.27.2',
useBuiltIns: "entry",
}
]
],
plugins: [
// 需要下载依赖 @babel/plugin-transform-runtime 和 @babel/runtime
'@babel/plugin-transform-runtime'
]
};core-js
core-js 包里含有以下模块:

参考每个文件夹的作用:https://github.com/zloirock/core-js#commonjs-api
js
// polyfill all `core-js` features, including early-stage proposals:
import "core-js";
// or:
import "core-js/full";
// polyfill all actual features - stable ES, web standards and stage 3 ES proposals:
import "core-js/actual";
// polyfill only stable features - ES and web standards:
import "core-js/stable";
// polyfill only stable ES features:
import "core-js/es";
// if you want to polyfill `Set`:
// all `Set`-related features, with early-stage ES proposals:
import "core-js/full/set";
// stable required for `Set` ES features, features from web standards and stage 3 ES proposals:
import "core-js/actual/set";
// stable required for `Set` ES features and features from web standards
// (DOM collections iterator in this case):
import "core-js/stable/set";
// only stable ES features required for `Set`:
import "core-js/es/set";
// the same without global namespace pollution:
import Set from "core-js-pure/full/set";
import Set from "core-js-pure/actual/set";
import Set from "core-js-pure/stable/set";
import Set from "core-js-pure/es/set";
// if you want to polyfill just required methods:
import "core-js/full/set/intersection";
import "core-js/actual/array/find-last";
import "core-js/stable/queue-microtask";
import "core-js/es/array/from";
// polyfill iterator helpers proposal:
import "core-js/proposals/iterator-helpers";
// polyfill all stage 2+ proposals:
import "core-js/stage/2";配置方式二 usage
1、这种方式和 entry 一样,也会将 polyfill 注入到全局。
2、它会根据目标环境,只把代码里用到的并且在目标浏览器里不支持的 api 进行垫片处理。
3、但是第三方依赖使用了不兼容 api,是不会垫片的。也就可能会报错。
所以使用这种方式,需要手动引入一些第三方依赖使用到的 polyfill。
babel.config.js
js
module.exports = {
presets: [
[
// 需要下载依赖 @babel/preset-env
'@babel/preset-env',
{
// modules 设置为 false 后,编译产生的辅助函数会以 esm 方式导入
// 这样有利于打包工具比如 webpack 静态分析,进行 treeshaking 减少代码体积。
modules: false,
// 设置代码需要兼容目标环境
// 如果为空对对象,则代表兼容最古老的浏览器
// 查找 targets 配置的顺序为
// 1、preset-env 下的 targets
// 2、babel 配置文件的 targets
// 3、package.json 中的 browserslist
// 4、项目根目录下的 browserslist
targets: {},
// useBuiltIns 为 usage 时,corejs 才能设置为对象形式
// 设置 proposals 的值
corejs: {
version: '3.27.2',
// 是否编译提案阶段 ES6+ API
proposals: false
},
useBuiltIns: "usage",
}
]
],
plugins: [
// 需要下载依赖 @babel/plugin-transform-runtime 和 @babel/runtime
'@babel/plugin-transform-runtime'
]
};配置方式三 false
不会在编译后的代码中添加 polyfill。
babel.config.js
js
module.exports = {
presets: [
[
// 需要下载依赖 @babel/preset-env
'@babel/preset-env',
{
// modules 设置为 false 后,编译产生的辅助函数会以 esm 方式导入
// 这样有利于打包工具比如 webpack 静态分析,进行 treeshaking 减少代码体积。
modules: false,
// 设置代码需要兼容目标环境,会向上寻找配置文件
targets: {},
// useBuiltIns 不为 false,这个选项才有用
corejs: '3.27.2',
useBuiltIns: false,
}
]
],
plugins: [
'@babel/plugin-transform-runtime'
]
};非全局注入方式
上面一、二两种方式是会把 polyfill api 注册到全局的。
@babel/plugin-transform-runtime
如果我们不想以全局的方式污染的方式垫平我们的 ES6+ API,我们 corejs 就不能为 false,并且优先使用 @babel/runtime-corejs3 这个包来垫平(设置为 3)
js
// package.json
"browserslist": [
"chrome 80"
]
module.exports = {
targets: {chrome: 80}, // 在这里添加
// 用于转换语法
presets: ['@babel/preset-env'],
plugins: [
[
"@babel/plugin-transform-runtime",
{
// 默认为 true,开启从 @babel/runtime 里引入辅助函数
// 设置为 fale 会变为内联方式
helpers: true,
// 默认为 true
// 我们的源码里面使用了 async function() {}等异步函数,
// 或者 fuction* myGenerator() {}这种 Generator 函数的话,
// 就会需要用到 regenerator-runtime 这个包来编译。
// Babel >= 7.18.0,regenerator-runtime 包里的内容,
// 会以局部变量的方式内联注入到我们的代码中,
// 这样我们就不需要全局提供一个 regeneratorRuntime 对象。
// 设置为 true 将 regeneratorRuntime 对象从 @babel/runtime 引入
// 设置为 false 会变为内联方式
regenerator: true,
// 这个配置项一旦不为 false,就代表会使用 polyfill。
// 就是用来设置我们的要垫平的 ES6+ API,以不污染全局局部变量方式垫平。
// 最好使用 core-js 3
corejs: "3"
}
]
]
}TIP
corejs 的三个值:
| 值 | 对应依赖 | 补充 |
|---|---|---|
| false(默认值) | @babel/runtime | |
| 2 | @babel/runtime-corejs2 | 1. 只能编译支持全局变量(如 Promise)和静态属性(如 Array.from);2. 不能编译实例相关方法([].includes) |
| 3 | @babel/runtime-corejs3 | 1. 既能编译能编译支持全局变量和静态属性,又能编译实例方法;2. 开启 proposals: true,还可以编译提案阶段的 API |
优化,设置 targets
js
// package.json
"browserslist": [
"chrome 80"
]
// 或者在顶层添加
module.exports = {
targets: {chrome: 80}, // 在这里添加
presets: ['@babel/preset-env'],
plugins: [
[
"@babel/plugin-transform-runtime",
{
...
}
]
]
}