@chris-ren
2016-06-01T09:03:44.000000Z
字数 5153
阅读 1031
Babel是一个通用的多用途 JavaScript 编译器。通过 Babel 你可以使用(并创建)下一代 JavaScript,以及下一代JavaScript 工具。
作为一种语言,JavaScript 在不断发展,新的标准/提案和新的特性层出不穷。在得到广泛普及之前Babel 能够让你提前(甚至数年)使用它们。
Babel主要特性如下:
*
Babel 把用最新标准编写的 JavaScript 代码向下编译成可以在今天随处可用的版本。 这一过程叫做“源码到源码”编译, 也被称为转换编译(也简称为转译)。
*
Babel 支持语法扩展,能支持像 React 所用的 JSX 语法,同时还支持用于静态类型检查的流式语法(Flow Syntax)。
*
Babel 由插件组成。通过利用现有的插件或者开发你自己的插件可以组合出满足你自身需要的转化管道。
Babel 的 CLI 是一种在命令行下使用 Babel 编译文件的简单方法。
安装命令如下:
$ npm install --global babel-cli
基本用法如下:
# 转码结果输出至终端
$ babel example.js
# 转码结果写入一个文件
# --out-file 或 -o 参数指定输出文件
$ babel example.js --out-file compiled.js
# 或者
$ babel example.js -o compiled.js
# 整个目录转码
# --out-dir 或 -d 参数指定输出目录
$ babel src --out-dir lib
# 或者
$ babel src -d lib
# -s 参数生成source map文件
$ babel src -d lib -s
上面是在全局环境下使用,如果要在项目中使用babel-cli,可以将babel-cli安装在项目中:
# 安装
$ npm install --save-dev babel-cli
然后,改写 包(package.json 。
{
// ...
"devDependencies": {
"babel-cli": "^6.0.0"
},
"scripts": {
"build": "babel src -d lib"
},
}
转码的时候,就执行下面的命令。
$ npm run build
babel-cli 工具自带一个 babel-node 命令,它提供一个支持ES6的交互运行环境。它不用单独安装,而是随 babel-cli 一起安装。
然后用 babel-node 来替代 node 运行所有的代码。
babel-node script.js //可以直接运行ES6脚本
但请注意这种方法并不适合正式产品环境使用。 直接部署用此方式编译的代码不是好的做法。 在部署之前预先编译会更好。 不过用在构建脚本或是其他本地运行的脚本中是非常合适的。
另一个运行babel常用的方法是babel-register 。这种方法只需要引入文件就可以运行Babel。
我们先在项目中创建index.js 文件。
console.log("Hello world!");
如果我们用 node index.js 来运行它是不会使用 Babel 来编译的。所以我们需要设置 babel-register 。
首先安装 babel-register 。
$ npm install --save-dev babel-register
接着,在项目中创建 register.js 文件并添加如下代码:
require("babel-register");
require("./index.js");
这样做可以把 Babel 注册到 Node 的模块系统中并开始编译其中 require 的所有文件。
现在我们可以使用 register.js 来代替 node index.js 来运行了。
$node register.js
注意:你不能在你要编译的文件内同时注册 Babel,因为 node 会在 Babel 编译它之间就将它执行了。(即babel-register 只会对 require 命令加载的文件转码,而不会对当前文件转码。另外,由于它是实时转码,所以只适合在开发环境使用。)
require("babel-register");
// 未编译的:
console.log("Hello world!");
如果某些代码需要调用Babel的API进行转码,就要使用 babel-core 模块。
安装命令如下。
$ npm install babel-core --save
然后,在项目中就可以调用 babel-core 。
var babel = require('babel-core');
// 字符串转码
babel.transform('code();', options);
// => { code, map, ast }
// 文件转码(异步)
babel.transformFile('filename.js', options, function(err, result) {
result; // => { code, map, ast }
});
// 文件转码(同步)
babel.transformFileSync('filename.js', options);
// => { code, map, ast }
// Babel AST转码
babel.transformFromAst(ast, code, options);
// => { code, map, ast }
配置对象 options ,可以参看官方文档 http://babeljs.io/docs/usage/options/ 。
下面是一个例子。
var es5Code = 'let x = n => n + 1';
var es6Code = require('babel-core')
.transform(es5Code, {
presets: ['es2015']
})
.code;
// '"use strict";\n\nvar x = function x(n) {\n return n + 1;\n};'
上面代码中, transform 方法的第一个参数是一个字符串,表示需要转换的ES5代码,第二个参数是转换的配置对象。
Babel的配置文件是 .babelrc ,存放在项目的根目录下。你可以通过安装插件(plugins)或预设(presets,也就是一组插件)来指示 Babel 去做什么事情。
基本 .babelrc 文件如下:
{
"presets": [],
"plugins": []
}
presets 字段设定转码规则,官方提供以下的规则集,你可以根据需要安装。
# ES2015转码规则
$ npm install --save-dev babel-preset-es2015
# react转码规则
$ npm install --save-dev babel-preset-react
# ES7不同阶段语法提案的转码规则(共有4个阶段),选装一个
$ npm install --save-dev babel-preset-stage-0
$ npm install --save-dev babel-preset-stage-1
$ npm install --save-dev babel-preset-stage-2
$ npm install --save-dev babel-preset-stage-3
然后,将这些规则加入 .babelrc 。
{
"presets": [
"es2015",
"react",
"stage-2"
],
"plugins": []
}
注意:插件预设presets是Babel 6 引入的概念,在Babel 5中没有插件预设概念,它默认包含ES2015的转换器插件。Babel 现在的目标不仅仅是作为ES2015的转换器,而是作为一个JavaScript工具平台,因此决定让所有的插件都是可插拔的。 即Babel 6 默认情况下并没有用来转换ES2015的代码的功能,但为了更容易的配置,提供了插件预设功能。
Babel 几乎可以编译所有时新的 JavaScript 语法,但对于 APIs 来说却并非如此。
比如说,下列含有箭头函数的需要编译的代码:
function addAll() {
return Array.from(arguments).reduce((a, b) => a + b);
}
最终会变成这样:
function addAll() {
return Array.from(arguments).reduce(function(a, b) {
return a + b;
});
}
然而,它依然无法随处可用因为不是所有的 JavaScript 环境都支持 Array.from 。
为了解决这个问题,引入了polyfill技术。
安装命令如下。
$ npm install --save babel-polyfill
然后,在脚本头部,加入如下一行代码。
import 'babel-polyfill';
// 或者
require('babel-polyfill');
为了实现 ECMAScript 规范的细节,Babel 会使用“助手”方法来保持生成代码的整洁。
由于这些助手方法可能会特别长并且会被添加到每一个文件的顶部,因此你可以把它们统一移动到一个单一的“运行时(runtime)”中去。
通过安装 babel-plugin-transform-runtime 和 babel-runtime 来开始。
$ npm install --save-dev babel-plugin-transform-runtime
$ npm install --save babel-runtime
然后更新 .babelrc :
{
"plugins": [
+ "transform-runtime",
"transform-es2015-classes"
]
}
现在,Babel 会把这样的代码:
class Foo {
method() {}
}
编译成:
import _classCallCheck from "babel-runtime/helpers/classCallCheck";
import _createClass from "babel-runtime/helpers/createClass";
let Foo = function () {
function Foo() {
_classCallCheck(this, Foo);
}
_createClass(Foo, [{
key: "method",
value: function method() {}
}]);
return Foo;
}();
这样就不需要把 _classCallCheck 和 _createClass 这两个助手方法放进每一个需要的文件里去了。
Babel 预设就是一些预先配置好的插件的集合,如果你想要做一些不一样的事情你会手动去设定插件,这和使用预设几乎完全相同。
首先安装插件:
$ npm install --save-dev babel-plugin-transform-es2015-classes
然后往 .babelrc 文件添加 plugins 字段。.
{
"plugins": [
"transform-es2015-classes"
]
}
这能让你对正在使用的转换器进行更细致的控制。完整的官方插件列表请见 Babel 插件页面。
代码检查工具
ESLint 是最流行的语法检查工具之一,因此Babel维护了一个官方的 babel-eslint 整合软件包。
首先安装 eslint 和 babel-eslint 。.
$ npm install --save-dev eslint babel-eslint
注意:兼容 Babel 6 的 babel-eslint 目前正处于预发行版本。 安装最新的 5.0 beta 版来兼容 Babel 6。
然后创建或使用项目现有的 .eslintrc 文件并设置 parser 为 babel-eslint 。.
{
+ "parser": "babel-eslint",
"rules": {
...
}
}
现在添加一个 lint 任务到 npm 的 package.json 脚本中:
{
"name": "my-module",
"scripts": {
+ "lint": "eslint my-files.js"
},
"devDependencies": {
"babel-eslint": "...",
"eslint": "..."
}
}
接着只需要运行这个任务就一切就绪了。
$ npm run lint
详细信息请查看 babel-eslint 或者 eslint 的文档。
单元测试工具
Mocha 则是一个测试框架,如果需要执行使用ES6语法的测试脚本,可以修改 package.json 的 scripts.test 。
"scripts": {
"test": "mocha --ui qunit --compilers js:babel-core/register"
}
上面命令中, --compilers 参数指定脚本的转码器,规定后缀名为 js 的文件,都需要使用 babel-core/register 先转码。