目录
babel 5.x -> 6.x 的变化非常大,许多模块分离出去,只是一些文档还语焉不详,这里略作整理。
babel-cli
如果你用过 CoffeeScript,或 TypeScript,那你对它们的编译过程一定很熟悉,babel-cli 模块同样也是一个编译的作用。
比如有一个 test.js 文件,内容如下:
let fun = () => console.log('babel')
那么执行 babel test.js
,会输出以下内容:
"use strict";
var fun = function fun() {
return console.log('babel');
};
除了 babel
命令外,babel-cli 包另有一个 babel-node
命令,它近似于 node,只不过它在运行代码前会预先编译 ES2015 的代码。
不论是 babel
命令还是 babel-node
命令,我们都可以通过命令行参数修改它们的行为,还可以通过新建一个 .babelrc
文件来配置。
但以上是 babel 5.x 的用法。
如果在 babel 6 里,执行 babel test.js
,只会输出原样的文本,因为 babel
不再包含任何 transform 功能,babel 6 里把它们作为插件(plugin)分割出去,需要我们自己定义,见下文说明。
babel 插件
在 babel 6 里,要转换 ES2015 的代码,需要自己配置插件,比如上面的示例:
let fun = () => console.log('babel')
我们执行 babel test.js
,babel 不会对文件做任何转换。我们需要一个 ES2015 arrow functions transform 插件。
-
安装插件
npm install babel-plugin-transform-es2015-arrow-functions
-
在目录下创建一个 .babelrc 文件,用于配置 babel,添加如下内容:
{ "plugins": ["transform-es2015-arrow-functions"] }
-
再执行
babel test.js
,我们得到如下转换结果:let fun = function () { return console.log('babel'); };
基本上 ES2015/ES7 的各种功能,babel 都提供了相应的插件用于转换,但如果我们要一个一个配置 – 那就太恼人了。所以 babel 还提供了一个方法:presets。
预置套餐
我们不妨把 presets 理解为套餐,不同套餐有不同的插件组合,比如 ES2015 preset 里打包了所有用于转换 ES2015 代码的插件,React preset 则打包了转换 react.js jsx 语法的插件。它们的用法同上面一致:
-
安装 preset
npm install babel-preset-es2015
-
配置 .babelrc 文件
{ "presets": ["es2015"] }
-
再执行
babel test.js
,我们会得到与 babel 5.x 一样的转换结果:'use strict'; var fun = function fun() { return console.log('babel'); };
babel-polyfill
babel 虽然可以转换各种 ES2015 语法及 jsx,但浏览器未提供原生支持的许多功能还是需要 polyfill,比如 Promise。
我们只要在代码中引入 babel-polyfill 就可以模拟出一个 ES2015 的环境,用法如下:
-
安装
babel-polyfill
npm install babel-polyfill --save
-
在入口文件中引用:
import babel-polyfill
babel-runtime
与 babel-polyfill 一样,babel-runtime 的作用也是模拟 ES2015 环境。只不过,babel-polyfill 是针对全局环境的,引入它,我们的浏览器就好像具备了规范里定义的完整的特性 – 虽然原生并未实现。
babel-runtime 更像是分散的 polyfill 模块,我们可以在自己的模块里单独引入,比如require(‘babel-runtime/core-js/promise’)
,它们不会在全局环境添加未实现的方法,只是,这样手动引用每个 polyfill 会非常低效。我们借助 Runtime transform 插件来自动化处理这一切。
至于要用 babel-polyfill 还是 babel-runtime,则需要根据具体需求。举个例子,如果一个库里引用了 babel-polyfill,别人的库也引用了 babel-polyfill,我们很可能会跑两个 babel-polyfill 实例,这里,使用 babel-runtime 会更合适。
webpack 中定义 babel-loader
在 webpack.config.js
里这样定义:
module: {
loaders: [
{
test: /\.js/,
loader: 'babel?presets[]=es2015,presets[]=react,plugins[]=transform-runtime'
}
]
}
babel-register
babel-register 是放在 node 里使用的。它的作用是替代 node 的 require
命令,与 node 自身的 require
不同,它可以加载 es2015、jsx 等类型文件。
用法如下:
require('babel-register')({presets: ['es2015', 'react']})
require('./app')
这样我们在 app 文件中就可以使用 es2015 与 jsx 语法了。