2 min read

babel 6 教程

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 插件。

  1. 安装插件

    npm install babel-plugin-transform-es2015-arrow-functions
    
  2. 在目录下创建一个 .babelrc 文件,用于配置 babel,添加如下内容:

    {
      "plugins": ["transform-es2015-arrow-functions"]
    }
    
  3. 再执行 babel test.js,我们得到如下转换结果:

    let fun = function () {
      return console.log('babel');
    };
    

    基本上 ES2015/ES7 的各种功能,babel 都提供了相应的插件用于转换,但如果我们要一个一个配置 – 那就太恼人了。所以 babel 还提供了一个方法:presets。

预置套餐

我们不妨把 presets 理解为套餐,不同套餐有不同的插件组合,比如 ES2015 preset 里打包了所有用于转换 ES2015 代码的插件,React preset 则打包了转换 react.js jsx 语法的插件。它们的用法同上面一致:

  1. 安装 preset

    npm install babel-preset-es2015
    
  2. 配置 .babelrc 文件

    {
      "presets": ["es2015"]
    }
    
  3. 再执行 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 的环境,用法如下:

  1. 安装 babel-polyfill

    npm install babel-polyfill --save
    
  2. 在入口文件中引用:

    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 语法了。

扩展阅读

  1. Clearing up the Babel 6 Ecosystem
报告问题 修订

如果你有自建 https 代理的需求,欢迎尝试 Phantom,一键搭建,方便快捷。查看 demo