Babel 使用指南

Babel 是什么?Babel 是一个 JavaScript 编译工具,可以把 ES6 或者下一代的 JavaScript 转换为当前浏览器或者当前运行环境所能识别的版本。

2018-09-01 更新:Babel 已发布了最新的版本 Babel7,本文只是基于 Babel6 的介绍,具有时效性
Babel 的一些新特性及用法以官方为准:https://babeljs.io/

Babel 提供了多种使用方式,可以在命令行中使用,也可以配合 webpack,gulp 等构建工具使用,下面来看一下各种使用方式。

在命令行中使用

Babel 提供了命令行工具,我们可以很方便的在命令行中使用。

babel-cli

首先要安装 babel-cli 工具

npm i g babel-cli

然后对于我们使用 es6 编写的文件直接运行如下命令即可:

# 把 main.js 编译后生成 compiled.js 文件
babel main.js --out-file compiled.js

当然也可以对整个目录使用:

babel ./src --out-dir ./dist

这样就把 src 下的所有 js 文件经过编译后输出到 dist 目录下,可以进行批量处理,一般会配合 Gulp 等构建工具使用。

babel-node

有些时候我们可能想直接运行 es6 编写的文件,这个时候使用 babel-node 即可,它不需要单独安装,已经包含在 babel-cli 里面了,使用时直接运行 babel-node index.js 即可,不过一般用于开发环境,线上环境还是编译后再运行比较好。

babel-register

babel-register 会改写 require 语法,为它添加一个钩子,每当使用 require 加载 JS 文件时,会先对文件进行转码,用法如下:

require('babel-register')({
// 可以根据需要添加插件
plugins: ['transform-async-to-generator']
});

require('./index');

这种用法一般在开发环境使用,生产环境还是需要编译后再运行。

在浏览器中使用

Babel 也可以直接在浏览器里使用,例如官方的 Try it out,我们直接在 HTML 页面中引入 babel-standalone 的 JS 文件即可,用法如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.18.1/babel.js"></script>
<script type="text/babel">
// 注意需要添加 type="text/babel"
const fn = () => {
console.log('123');
};

fn();
</script>
</body>
</html>

不过这种用法一般不推荐在生产环境使用,因为使用时要先把 JS 转义后再执行,影响效率,最好还是编译后再在页面中引入。

配合 webpack 使用

Webpack 作为一个强大的构建工具,一般少不了 babel-loaderbabel-loader 一般用于处理 JS 或者 JSX 文件,作为一个加载器然后再配合一些 presets 和 plugins 对文件进行编译处理。使用时需要先安装 babel-core,下面就来看一个简单的 React 项目的配置。

首先需要安装相关的依赖:

npm i webpack babel-core babel-loader babel-preset-env babel-preset-react babel-plugin-transfrom-runtime --save-dev
npm i babel-runtime --save

下面是我们的 webpack 配置文件示例:

// webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, './dist')
},
module: {
rules: [
{
test: /\.jsx?$/,
loader: 'babel-loader'
exclude: /node_modules/
}
]
}
}

然后在项目跟目录建一个 .babelrc 文件,可以根据需要配置 presets 和 plugins:

{
"presets": [
[
"env": {
"targets": {
"browsers": [ ">0.25%", "not ie 11", "not op_mini all"]
}
}
]
"react"
],
"plugins": [
"transform-runtime"
]
}

运行 webpack 时,babel-loader 会根据 .babelrc 里面的配置对 js 或者 jsx 文件进行处理,由于 babel 只会转义新的语法(例如箭头函数),并不会对新的 api 进行转义(例如 Promise,Generator),因此我们还需要 babel-plugin-transfrom-runtimebabel-runtime

关于 babel-runtime 的疑问可以参考这里:https://segmentfault.com/q/1010000005596587

常用的 presets 及 plugins

Babel 一般会配合 presets 和 plugins 使用,常用的 presets 有以下两个:

stage-x

ESMAScript 新特性提案分为了不同的阶段,从 stage0 到 stage4, Babel 也针对不同的阶段提供了对应的 presets,如下所示:

ECMAScript 不同阶段的提案可以参考这里:https://github.com/tc39/proposals

babel-plugin-transform-runtime

由于 Babel 只会转换新的语法,而不会转换新的 API(例如 Generator,Set,Promise,Proxy 等),以及一些定义在全局对象上的方法(如,Array.from())也不会转换,因此我们需要使用一些 babel-runtime 提供的工具函数,但是为了防止工具函数在每个文件里重复生成,Babel 又提供了 babel-plugin-transform-runtime 插件,这样的话就减少了代码体积、去掉了重复的代码,使用时直接安装即可:

npm i babel-plugin-transform-runtime --save-dev
npm i babel-runtime --save

plugins

关于插件,一般 state-x 里面已经包含了很多插件,如果不想引入 stage-x 的话,可以单独在 plugins 配置,比如装饰器的配置,babel-plugin-transform-decorators-legacy

{
"presets": [
"env",
"react"
],
"plugins": [
"transform-runtime",
"transform-decorators-legacy"
]
}

当然如果我们引入了 stage-2stage-1 或者 stage-0 的话,就不用单独配置了,因为它们已经包含了装饰器。

参考资料