翻译链接:https://babeljs.io/docs/en/usage
Babel本身自带了一些工具,便于用户使用。下面会给一个关于这些工具的概括。
概述
这份使用说明是展示如何将ES6+的语法转化为目前浏览器能识别的代码。这个步骤会涉及到转化新语法和一些缺失方法的填充(polyfill)。
设置整个过程需要如下:
运行下面命令,安装包。
1
2npm install --save-dev @babel/core @babel/cli @babel/preset-env
npm install --save @babel/polyfill创建babel.config.js文件在你的根目录下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16const presets = [
[
"@babel/env",
{
targets: {
edge: "17",
firefox: "60",
chrome: "67",
safari: "11.1",
},
useBuiltIns: "usage",
},
],
];
module.exports = { presets };运行下面命令,将代码从src目录下编译到lib目录下。
1
./node_modules/.bin/babel src --out-dir lib
CLI的基本用法
自从Bable 7之后,所有需要的Babel模块,都是npm独立的包发布在域名@babel下。这样做,对于一些特殊的案例下,会比较灵活。接下来,我们看一下@babel/core
和@babel/cli
。
Core
有关Babel的核心功能,都被放到了@babel/core
模块下。你可以直接在JS代码中直接require
进来。1
2const babel = require("@babel/core");
babel.transform("code", optionsObject);
做为使用者,你可能需要安装其它工具,做为接口和@babel/core
一起使用,并集成在你的开发流程中。尽管如此,你仍然会需要查看它的文档,学习options。
Core tool
@babel/cli
允许你在终端使用babel。下面是安装命令和基本用法例子:1
2npm install --save-dev @babel/core @babel/cli
./node_modules/.bin/babel src --out-dir lib
他会解析你在src下的JS,经过一系列的转化,在lib目录下输出。由于,我们没有命令它做任何转化,最后的输出会和输入一致。我们可以通过设置option来命令babel做一些转化。
例子中,我们使用了--out-dir
option。你可以通过--help
来查看cli还支持哪些option。对于我们来说,比较重要的两个option是:plugins和presets。
Plugins & Presets
转化以Plugins的形式出现。这些插件都是小的JS程序,指导Babel转化代码。你也可以创建自定义Plugins将转化应用在代码上。将ES6+语法转化成ES5,我们可以利用官方插件:@babel/plugin-transform-arrow-functions
:1
2npm install --save-dev @babel/plugin-transform-arrow-functions
./node_modules/.bin/babel src --out-dir lib --plugins=@babel/plugin-transform-arrow-functions
这样,任何箭头函数都会转化成ES5的兼容函数:1
2
3
4
5const fn = () => 1;
// converted to
var fn = function fn() {
return 1;
};
同样,ES6+除了箭头函数的语法外,还有别的。我们不可能为这些语法,一个一个的添加插件。Babel提供给我们Preset属性。这个属性是一个预先定义好的插件集。
和Plugins一样,你可以创建属于自己的Preset。在我们例子中,有一个非常不错的preset:env
。1
2npm install --save-dev @babel/preset-env
./node_modules/.bin/babel src --out-dir lib --presets=@babel/env
不需要其它的配置,env
已经包括了将ES6+转化成当前浏览器支持的版本的所有的插件。presets同样可以有option。不是从终端配置option,接下来我们看下从配置文件中,如何配置option。
配置
基于需求,会有多种方式配置。可以阅读Configure Babel了解更多信息。
现在,创建一个babel.config.js
的文件,内容如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15const presets = [
[
"@babel/env",
{
targets: {
edge: "17",
firefox: "60",
chrome: "67",
safari: "11.1",
},
},
],
];
module.exports = { presets };
现在,env
会下载那些现在浏览器无法正常使用的插件,转化代码。以上,我们所做的都是转化语法。接下来,让我们看下polyfill。
Polyfill
@babel/polyfill
包括core-js
和一个自定义的`regenerator runtime`来模拟一个ES6+的环境。
这就意味着,你可以用内置的语法,比如Promise
或者WeakMap
,静态方法比如Array.from
或者Object.assign
,原型方法比如Array.prototype.includes
,和generator函数(需要用regenerator插件)。Polyfill会被添加到全局作用域下。
对于库/工具开发者而言,Polyfill提供的太重。如果你不使用类似Array.prototype.includes
原型方法,你可以利用transform runtime,代替@babel/polyfill
,避免污染全局环境。因为plugin-transform-runtime
提供了一个方法到core-js
的一个别名。你可以直接用这个插件,无需再polyfill。如下:1
2
3
4// in
var sym = Symbol();
var promise = new Promise();
console.log(arr[Symbol.iterator]());
1 | // out |
如果你确切知道哪些功能需要你polyfill,你可以直接从
core-js
中require
他们。
幸运的是,env
preset提供了一个选项useBuiltIns
给我们。当我们将它设置成"usage"
时,env
就会应用最新的优化。这些优化包括了你需要的polyfill。配置如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16const presets = [
[
"@babel/env",
{
targets: {
edge: "17",
firefox: "60",
chrome: "67",
safari: "11.1",
},
useBuiltIns: "usage",
},
],
];
module.exports = { presets };
基于上面的配置,Babel可以检测你目标环境需要转化的语法问题和一些polyfill的内置方法。比如下面代码:1
Promise.resolve().finally();
就会转化成(因为edge 17没有Promise.prototype.finally
方法):1
2require("core-js/modules/es.promise.finally");
Promise.resolve().finally();
如果我们没有设置env
里useBuiltIns
为usage
,我们必须在入口文件头部require整个polyfill进来。
总结
我们利用@babel/cli
将babel运行在终端,@babel/polyfill
为JS的一些特征填充。env
预设转化和填充目标浏览器没有的功能。