下一代JavaScript语法编译器Babel

 2016年03月20日    198     声明


当前最新的JavaScript语法标准是ECMAScript 6ES2015),ES2015JavaScript带来了很多新特性,如:Promise对象Generator函数Class等。但是这些对象浏览器和低版本的Node.js(Node.js自v4.0+开始支持ES2015特性)中,在并不能或部分不能支持ES2015特性,这时我们可以使用Babel对语言进行转换。


  1. 1Babel介绍
  2. 使用Babel CLI命令行
  3. Gulp中使用Babel
  4. Browserify(浏览器)中使用
  5. 使用BabelNode.js API
  6. React中使用

1. Babel介绍

Babel是一个JavScript语言编译器(转换器),可以将下一代标准的JavaScript转换为符合ES5标准的JavaScript。其支持的转换功能包括:

1.1 ES2015及其后

Babel支持对JavaScript最新版本语法的转换。这样你可以使用最新的语法的特性,而不必等待浏览器的支持。通过Babelbabel-preset-es2015插件,可以实现对ES2015语法的转换。下面是Babel所支持的语法:

  • Arrow functions
  • Async functions
  • Async generator functions
  • Classes
  • Class properties
  • Computed property names
  • Constants
  • Decorators
  • Default parameters
  • Destructuring
  • Exponentiation operator
  • For-of
  • Function bind
  • Generators
  • Let scoping
  • Modules
  • Module export extensions
  • Object rest/spread
  • Property method assignment
  • Property name shorthand
  • Rest parameters
  • React
  • Spread
  • Template literals
  • Type annotations
  • Unicode regex


1.2 JSXReact

Babel支持ReactJSX语法Flux框架,通过Babelbabel-preset-react插件,可以实现对React相关语法的转换。在Sublime编辑器中,还可以使用Babel提供babel-sublime包,来对相关语法高亮显示。


1.3 可扩展

Babel使用插件机制,你可以使用现有的插件或自己编写插件来构建转换管道,使用或新建插件都非常简单。


Babel提供了各种各样的使用方式,你可以使用它的CLI命令行模块单独转换,也可以结合BrowserifyGulp等构建工具使用。Babel的支持的使用方式请参考:使用Babel


下面是几种常用的Babel使用:

2. 使用Babel CLI命令行

2.1 安装

你可以全局安装Babel CLI,但更推荐安装在当前项目中。

在当前项目中安装Babel CLI命令如下:

npm install --save-dev babel-cli

安装完成后,package.json文件中会babel-cli配置字段:

{
  "name": "my-project",
  "version": "1.0.0",
  "devDependencies": {
    "babel-cli": "^6.0.0"
  }
}


2.2 使用

全局安装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 dist
# 或
$ babel src -d dist

# 使用 -s 参数生成source map文件
$ babel src -d dist -s

当前项目下,我们可以通过修改package.json文件,将命令添加到npm scripts命令中。在package.json文件中添加如下配置项:

"scripts": {
  "build": "babel src -d dist"
}

配置完成后,我们可以通过以下命令来执行转换:

npm run build


注意:在v6.x版本之前,Babel启用了一定的转换预设,但v6.x版本之前未启用任何默认的转换预设。在使用前,我们应该配置转换预设,详见创建.babelrc配置文件


2.3 创建.babelrc配置文件

在前面转换命令中,Babel实际上未进行任何转换。这时,我们需要创建一个.babelrc文件,并在文件中配置一些插件和转码预设(设置)。文件格式如:

{
  "presets": [],
  "plugins": []
}

在进行ES2015转码时,我们需要ES2015 Preset模块,安装命令如下:

npm install babel-preset-es2015 --save-dev

安装后,配置到.babelrc文件中:

echo '{ "presets": ["es2015"] }' > .babelrc

配置完成.babelrc文件后,再次执行npm run build命令可以看到,相关ES6语法已被转换为ES5


3. 在Gulp中使用Babel

3.1 安装

Babel提供了gulp-babel插件,这个插件是一个Gulp中间件,可以像其它Gulp插件使用。

在当前项目中安装gulp-babel命令如下:

npm install --save-dev gulp-babel


3.2 使用gulp-babel

安装后,我们在可以Gulp的配置脚本gulpfile.js文件中配置如下:

var gulp = require("gulp");
var babel = require("gulp-babel");

gulp.task("default", function () {
  return gulp.src("src/")
    .pipe(babel())
    .pipe(gulp.dest("dist"));
});

当使用gulp-sourcemaps时,配置如下:

var gulp = require("gulp");
var sourcemaps = require("gulp-sourcemaps");
var babel = require("gulp-babel");
var concat = require("gulp-concat");

gulp.task("default", function () {
  return gulp.src("src/**/*.js")
    .pipe(sourcemaps.init())
    .pipe(babel())
    .pipe(concat("all.js"))
    .pipe(sourcemaps.write("."))
    .pipe(gulp.dest("dist"));
});


注意:在Gulp中使用Babel时,同样需要创建.babelrc配置文件


4. 在Browserify(浏览器)中使用

4.1 安装

Babel提供了babelify插件,通过这个插件可以转换Browserify中的ES6语法。

在当前项目中安装babelify命令如下:

npm install --save-dev babelify


4.2 使用babelify

在命令行中使用:

browserify script.js -t babelify --outfile bundle.js

通过Node API转换:

browserify({ debug: true })
  .transform(babelify);

var fs = require("fs");
var browserify = require("browserify");
var babelify = require("babelify");

browserify({ debug: true })
  .transform(babelify)
  .require("./script.js", { entry: true })
  .bundle()
  .on("error", function (err) { console.log("Error: " + err.message); })
  .pipe(fs.createWriteStream("bundle.js"));


转换选项

命令行:

browserify -d -e script.js -t [ babelify --blacklist regenerator ]

Node API:

browserify().transform(babelify.configure({
  blacklist: ["regenerator"]
}))

package.json

{
  "transform": [["babelify", { "blacklist": ["regenerator"] }]]
}


在浏览器中使用

Babel支持在浏览器中使用,在浏览器中单独使用时,需要安装babel-standalone模块。安装后引用其中的babel.min.js文件即可,也可以直接使用DNSJS上文件:

<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.4.5/babel.min.js"></script>
<script type="text/babel">
// Your ES6 code
</script>

在浏览器中单独引用时,会在页面加载后实时,这会对性能造成一定影响。所以,更推荐使用browserifybabelify线下完成转换。


注意:在Browserify中使用Babel时,同样需要创建.babelrc配置文件


5. 使用BabelNode.js API

5.1 安装

Babel提供了Node.js API,如果你的代码需要在Node.js中转换,可以安装babel-core模块。

npm install --save babel-core


5.2 使用babel-core

安装后,我们可以像下面这样引用:

var babel = require("babel-core");
babel.transform(code, [options]) // => { code, map, ast }


5.3 babel-core提供的API

babel.transform(code, [options])

transform()方法会转换传入的代码code,并返回转换后的代码、source map等。


babel.transformFile(filename, [options], callback)

异步转换filename文件中的内容。


babel.transformFileSync(filename, [options], callback)

同转换filename文件中的内容,babel.transformFile()方法的同步版本。


options是一个转包含换选的对象,详细请参考官方文档:Babel Options


6. 在React中使用

Babel支持对ReactJSX语法和Flux框架的转换,在React中使用请参考:React 入门示例