Babel7是Babel最新的一个大版本的更新,它启用新的包名方式以区分官方包和非官方包,它现在也开始支持TypeScript。它引入了新的配置方式babel.config.js

之前对Babel有所了解,工作中也有使用,但一直觉得自己对它认识很模糊,所以整理一篇文章让自己对它认识更清晰。

配置

Babel7支持三种配置方式:babel.config.js,.babelrc/.babelrc.jspackage.json#babel

Babel7中可以使用babel.config.js进行配置了,使得配置的灵活性得到大的提升。它的配置内容没啥变化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
module.exports = function(api) {
api.cache(false);
const presets = [
[
"@babel/env",
{
useBuiltIns: "usage",
targets: {
browsers: [
"Chrome >= 49",
"Firefox >= 45",
"Safari >= 10",
"Edge >= 13",
"iOS >= 10",
"Electron >= 0.36"
]
}
}
]
];
return { presets };
};

你可以通过使用Node.jsAPI,进行配置,例如:

1
2
3
4
5
6
7
8
const presets = [ ... ];
const plugins = [ ... ];

if (process.env["ENV"] === "prod") {
plugins.push(...);
}

module.exports = { presets, plugins };

overrides

你可以根据不同的目录配置不同的配置项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module.exports = {
presets: [
// defeault config...
],
overrides: [{
test: ["./node_modules"],
presets: [
// config for node_modules
],
}, {
test: ["./tests"],
presets: [
// config for tests
],
}]
};

ignore

指定忽略编译目录或文件

preset-env

preset-env包含一组可以编译已正式发布的JavaScript最新语法(JavaScript每年会发一个版本)的插件。你可以可以指定项目运行的环境,preset-env使用对应的插件将项目代码编译成在这些指定的环境下可以正常运行。

Babel7 放弃Stage-presets@babel/preset-stage-0 等),原因在官网博客有说明

配置例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const presets = [
[
"@babel/env",
{
targets: {
edge: "17",
firefox: "60",
chrome: "67",
safari: "11.1",
},
useBuiltIns: "usage", // 根据需要引入 polyfill
},
],
];

module.exports = { presets };

@babel/polyfill

Babel只负责语法转换,比如将ES6的语法转换成ES5,但对于新的JavaScript语法规则中新增的对象或方法Babel本身是不支持编译的。例如:

  1. 全局对象:Promise、WeakMap 等。

  2. 全局静态函数:Array.from、Object.assign 等。

  3. 实例方法:比如 Array.prototype.includes 等。

我们需要引入第三方插件支持这些方法的在不支持的环境中的正常使用。

@babel/polyfill可以完美的支持这些新增的方法或对象。

你只需要安装它,并将它打包进项目中。

1
$ yarn add @babel/polyfill

你需要确保@babel/polyfill能够优先被加载解析,因为它会对JavaScript原生对象进行修改和处理。

如果你使用webpack打包项目,你可以:

1
2
3
module.exports = {
entry: ["@babel/polyfill", "./app.js"],
};

@babel/polyfill会对全局对象进行污染,并且可能会加入你用不到的新方法。你可以通过@babel/runtime插件在你需要的地方引入你使用到的新方法,而不会造成全局污染。

注意 如果使用@babel/runtime一些实例方法你将无法使用,例如:Array.prototype.includes。因为它必须在原生对象的原型链上进行修改。

@babel/plugin-transform-runtime、 @babel/runtime

安装

1
2
$ yarn add -D @babel/plugin-transform-runtime
$ yarn add @babel/runtime

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"corejs": false,
"helpers": true,
"regenerator": true,
"useESModules": false
}
]
]
}

注意 一般库或工具中使用@babel/runtime,因为它可以避免全局的污染。如果是项目中可以直接使用@babel/polyfill或者在@babel/preset-env中配置useBuiltIns = usage