[开发工具] Babel 配置入门教程

什么是 Babel

Babel 是一个 ECMAScript 编译器,可以将新一代的 ES 语法转为旧一代的 ES 语法,甚至是转换 ES 的超集语言(如 jsx, typescript 等)为 ECMAScript 代码。

截止发稿日期,Babel 的版本号为 7.4.x。在没有特殊说明的情况下,我将在此版本上进行介绍。

目前,所有的 Babel 7.x 版本的官方 npm 包都在 @babel 命名空间下。

常用 Babel 包及说明

  • @babel/core
    Babel 的核心组件,只要使用 Babel 就必须要安装此 npm 包。

  • @babel/cli
    Babel 的终端命令,如果想在终端中调用 babel 命令,需要安装此 npm 包。

  • @babel/node
    Babel 的交互式解释器,此包中带有 babel-node 命令,此命令可以像 node 一样使用,但在实际使用前会先进行代码转换。
    但是,在 babel-node 中不支持 letconst

  • @babel/register
    node中直接采用新的语法书写执行时,用于注册Require hooknpm 包。

  • @babel/plugin-*
    @babel/plugin-*Babel 的语法支持插件,主要包含下列三类:

    • @babel/plugin-transform-*
    • @babel/plugin-proposal-*
    • @babel/plugin-syntax-*

    三者的主要区别是:

    1. @babel/plugin-syntax-* 只提供给 Babel 的支持,但不提供转换,剩余两者都提供转换。
    2. @babel/plugin-transform-* 是对 ECMAScript 中已定义的语法及超集语言的转换,而 @babel/plugin-proposal-* 是对草案中提到的语法进行转换,换句话说,@babel/plugin-proposal-* 转换的语法,不能保证以后规则不会变。
    3. 但如果转换插件是在草案阶段实现的,且称为 ECMAScript 的标准语法后,实现没有改变,插件可能仍然保留 @babel/plugin-proposal-* 命名而不改变。
  • @babel/preset-*
    Babel 的预置配置,不通的配置一般包含有不同的插件,并进行了适当地设置。
    Babel 的预置配置使用最多的是@babel/preset-env,有较多的配置项,,常用选项按照 选项名: 类型 = 默认值 的格式给出:

    • targets: string | Array<string> | { [string]: string } = {}
      描述您为项目支持/定位的环境, 如: "> 0.25%, not dead", { "chrome": "58", "ie": "11" }, 默认情况下将转换所有ECMAScript 2015+代码
    • modules: "amd" | "umd" | "systemjs" | "commonjs" | "cjs" | "auto" | false = "auto"
      启用将ES6模块语法转换为其他模块类型。 将此设置为false不会转换模块。 另请注意,这cjs只是一个别名commonjs。
      其余选项可参考@babel/preset-env 的选项

使用 Babel

配置及配置文件

配置为一个 object 对象,其主要有以下两个属性:

  • plugins: 插件列表,Array 类型。
    每一项为一个插件,可以是以下几种格式
    • '插件名称',直接为插件的名称,如 @babel/plugin-transform-react-jsx, 如果插件名称以 babel-plugin- 开头,可以将其省略,如 babel-plugin-my-plugin 可以省略为my-plugin
    • ['插件名称', { /* 选项 */ }],使用插件,并设置选项
    • pluginObject,使用插件对象,一般通过 require 导入的插件
    • [pluginObject, { /* 选项 */ }],使用插件,并设置选项
      插件会按照在列表中的顺序,被依次应用
  • presets: 预设列表,Array 类型。
    每一项为一个预设,可以是以下几种格式
    • '预设名称',直接为预设的名称,如 @babel/preset-transform-react-jsx, 如果预设名称以 babel-preset- 开头,可以将其省略,如 babel-preset-my-preset 可以省略为my-preset
    • ['预设名称', { /* 选项 */ }],使用预设,并设置选项
    • presetObject,使用预设对象,一般通过 require 导入的预设
    • [presetObject, { /* 选项 */ }],使用预设,并设置选项
      预设会按照在列表中的反向顺序,被依次应用。
      预设会在插件之后引用。

根据使用的场景不同,可能需要将配置单独写入到配置文件中

Babel 目前支持两种配置文件:

  • .babelrc 其本质为 JSON5 文件,其内容作为配置
  • babel.config.js 其本质为 nodejs 的 commonjs 模块文件,其导出作为配置

附 babel 配置举例

module.exports = {
    plugins: [
        '@babel/plugin-proposal-async-generators',
        '@babel/plugin-proposal-async-to-generator',
        '@babel/plugin-proposal-class-properties',
        '@babel/plugin-proposal-do-expressions',
        '@babel/plugin-proposal-function-bind',
        '@babel/plugin-proposal-logical-assignment-operators',
        '@babel/plugin-proposal-numeric-separator',
        '@babel/plugin-proposal-object-rest-spread',
        '@babel/plugin-proposal-optional-catch-binding',
        '@babel/plugin-proposal-optional-chaining',
        '@babel/plugin-proposal-private-methods',
        '@babel/plugin-proposal-throw-expressions',
        ['@babel/plugin-transform-typescript', {isTSX: true, jsxPragma: 'createElement'}],
        ['@babel/plugin-transform-react-jsx', {pragma: 'createElement', throwIfNamespace: false}],
    ]
};

在终端中进行编译

需要配置好配置文件,并安装以下两个必须的 npm 包及其他用到的插件及预置等:

  • @babel/core
  • @babel/cli

之后可以使用 babel 命令进行编译,我一般会在 package.json 中配置命令,如下:
babel src --out-dir lib -x .ts,.tsx -s
其中:

  • src 为要编译的文件(或要编译文件所在的目录)
  • --out-dir lib 为设置编译结果的输出目录,其中 lib 为输出目录。如果是编译一个文件怎用 --out outFile outFile 为输出文件
  • -x .ts,.tsx 设置要编译的文件后缀,默认情况下只编译 .es6,.js,.es,.jsx,.mjs 五种后缀的文件,这里我还希望编译 .ts,.tsx,所以我还使用了此选项
  • -s 选项表示生成独立的 .map 文件,便于后期调试

在终端中采用交互式执行

需要配置好配置文件,并安装以下两个必须的 npm 包及其他用到的插件及预置等:

  • @babel/core
  • @babel/node

之后可以使用 babel-node 命令交互式执行,如果需要支持 .es6,.js,.es,.jsx,.mjs 五种后缀以为的文件通过 require 导入,需要使用 -x 选项,使用方式同 babel 命令

在 node 上下文中使用

需要配置好配置文件,并安装以下两个必须的 npm 包及其他用到的插件及预置等:

  • @babel/core
  • @babel/register

之后在 node 的入口文件第一行前插入 require('@babel/register'); 如果是采用 ES6 的 import, 则是 import '@babel/register';

在 node 中调用 babel 进行转换

只需要安装 @babel/core,之后按照如下格式执行即可:
require('babel-core').transform('code', options);
其中:

  • 'code' 是要转换的代码
  • options 是要 babel 的配置

常用 Babel 语法转换插件

以下按照 ES6+ 的常用特性及变成语言罗列,后面附相关插件,其中若未附带@babel/plugin-syntax-*且未特别说明则表示 Babel 默认支持此类语法的解析,部分后面附有常用选项,常用选项按照 选项名: 类型 = 默认值 的格式给出。