Babel 对 Modern JavaScript 的推动功不可没,它使得开发者可以愉悦的享受新的语法带来的快感,然后再翻译成生产环境需要支持的旧的代码集。
JavaScript 的功能和版本之争吵了很多年,Babel 是个用行动来代替争吵的勇士。
当然更好的消息是,越来越多的功能被 node/浏览器 原生给实现,这意味着,越来越少的东西需要被编译。
## 概念入门
Babel 是一个转码器,它可以将 JavaScript 中的一个新语法进行转换,让旧的引擎支持。
翻译中的两个概念是 plugin & preset。
plugin
每个 plugin 对应的是一个 feature,可以在这里看到各个版本中对应的更新和 node 的支持度:http://node.green/
下面列出了 ECMA 近期版本中的一些变化点。每个点都是一个 plugin。
ECMAScript 2015
ES2015 确实是一个很大的改变,光看这个列表就能知道。使用该这些 plugins 可以将代码编译为 ES5 环境能执行的。
- es2015-template-literals
- es2015-literals
- es2015-function-name
- es2015-arrow-functions
- es2015-block-scoped-functions
- es2015-classes
- es2015-object-super
- es2015-shorthand-properties
- es2015-duplicate-keys
- es2015-computed-properties
- es2015-for-of
- es2015-sticky-regex
- es2015-unicode-regex
- es2015-constants
- es2015-spread
- es2015-parameters
- es2015-destructuring
- es2015-block-scoping
- es2015-typeof-symbol
- es2015-modules-commonjs
ECMAScript 2016
- transform-exponentiation-operator
ECMAScript 2017
- syntax-trailing-function-commas
- transform-async-to-generator
preset
preset 就是一组 plugin 的集合,可以让开发都不用一个个的单独配置 plugin。
es2015, es2016, es2017 是目前三个主要的版本。
这三个版本中,相互没有包含关系,里面的 plugin 都是 ecma 所对应的 features.
最近加了一个 latest,它其实就是将上面三个 preset 再次包装了一次,使用起来更方便了。
1 | presets: [ |
除了 上面说的 ECMAScript 标准的集合,也会有一些自定义的集合可用。像
- babel-preset-react
## Babel 上手速成
- .babelrc
- babel-cli
- babel-register
Babel 常有两种使用方式,一个是即时的,常用在开发环境使用,快速,方便。
另一个是编译用的,用在线上发布使用。
runtime
在开发模式中,我们会用 babel-register 来做时时支持。但这样的效率不高,不适合用于 production 环境。
一个标准的 babel 配置如下,开发环境可以 require
这个配置,就能正常运行新的 feature 了。
1 | require("babel-core/register")({ |
build
线上发布会使用 build 后的代码,.babelrc
是一个 build 所需要的配置文件,它的配置内容和 runtime 是一样的,只是写法有所不同。
1 | { |
babel-register
babel-register 模块改写 require 命令,为它加上一个钩子。此后,每当使用 require 加载 .js、.jsx、.es和 .es6 后缀名的文件,就会先用 Babel 进行转码。
需要注意的是,babel-register 只会对 require 命令加载的文件转码,而不会对当前文件转码。另外,由于它是实时转码,所以只适合在开发环境使用。
1 | require("babel-core/register")({ |
entry.js 中是不能使用新语法的。一定要定义在另一个新文件中。
## 最佳实践
Babel 可以 javascript 翻译成任何一个你想到的旧版本。但如果环境已经支持的一些 feature 再被 transpile,就不够优雅了。
所以,更好的作法是,根据具体需求,来选择 preset/plugin,就翻译哪些。
Node 7 对这些语法的支持,已经接近完美了。(只差 async/esm),如果用到了这两个 feature,就直接加这些 plugin 好了。
实战
关于代码的组织结构,参考了 Rails,而不是 node/web 常用的
src
方案,因为我们相信很快,代码就不用再 build,而且直接上线。
Server 端用 Node.js 6.4.0,开发中用到的 feature 列表中,只有两项还暂不支持:
- es2015 module-commonjs
- es2017 async-functions
所以在配置 babel 时,根据自己的需求,只需要单独引入就可以了,这样,编译出来的代码几乎相同了,.babelrc
配置如下:
1 | { |
## REF::