Babel 配置文件

一、配置文件

在前面几小节,我们已经简单使用过Babel的配置文件了。现在我们来深入学习它。

无论是通过命令行工具babel-cli来进行编译,还是webpack这类的构建工具,通常情况下,我们都需要建立一个Babel配置文件来指定编译的规则。

Babel的配置文件是Babel执行时默认会在当前目录寻找的文件,主要有.babelrc,.babelrc.js,babel.config.js和package.json。它们的配置项都是相同,作用也是一样的,只需要选择其中一种。

对于.babelrc,它的配置是这样子

  {
    "presets": ["es2015", "react"],
    "plugins": ["transform-decorators-legacy", "transform-class-properties"]
  }

对于babel.config.js和.babelrc.js,它的配置是一样的,通过module.exports输出配置项

  module.exports = {
    "presets": ["es2015", "react"],
    "plugins": ["transform-decorators-legacy", "transform-class-properties"]
  }

对于package.json,就是在package.json中增加一个babel属性和值,它的配置是这样子

  {
    "name": "demo",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "",
    "babel": {
      "presets": ["es2015", "react"],
      "plugins": ["transform-decorators-legacy", "transform-class-properties"]
    }
  }

仔细观察上述几种配置文件,会发现它们的配置项其实都是plugins和presets。

另外,除了把配置写在上述这几种配置文件里,我们也可以写在构建工具的配置里。对于不同的构建工具,Babel也提供了相应的配置项,例如webpack的babel-loader的配置项,其本质和配置文件是一样的,大家学会配置上述的一种,自然也就会其它的了,不再单独讲解。

配置文件总结起来就是配置plugins和presets这两个数组,我们分别称之为插件数组和预设数组。

除了plugins和presets这两个配置项,还有minified、ignore等,但我们平时都用不到,大家还是把精力放在plugins和presets上。

推荐使用后缀名是js配置文件,因为可以使用js做一些逻辑处理,适用性更强。举一个例子

  //  这里只是举个例子,实际项目中,我们可以传入环境变量等来做处理
  var year = 2020;
  var presets = [];
  if (year > 2018) {
    presets = ["@babel/env"];
  } else {
    presets = "presets": ["es2015", "es2016", "es2017"],
  }
  module.exports = {
    "presets": presets,
    "plugins": []
  }

二、插件与预设

plugin代表插件,preset代表预设,它们分别放在plugins和presets,每个插件或预设都是一个npm包。

本节开头提到了通过Babel配置文件来指定编译的规则,所谓编译的规则,就是在配置文件里列出的编译过程中会用到的Babel插件或预设。这些插件和预设会在编译过程中把我们的ES6代码转换成ES5。

Babel插件的数量非常多,处理ES2015的有

  • @babel/plugin-transform-arrow-functions
  • @babel/plugin-transform-block-scoped-functions
  • @babel/plugin-transform-block-scoping
    ……

处理ES2018的有

  • @babel/plugin-proposal-async-generator-functions
  • @babel/plugin-transform-dotall-regex
    ……

所有的插件都需要先安装npm包到node_modules后才可以使用。

Babel插件实在太多,假如只配置插件数组,那我们前端工程要把ES2015,ES2016,ES2017…下的所有插件都写到配置项里,我们的Babel配置文件会非常臃肿。

preset预设就是帮我们解决这个问题的。预设是一组Babel插件的集合,用大白话说就是插件包,例如babel-preset-es2015就是所有处理es2015的二十多个Babel插件的集合。这样我们就不用写一大堆插件配置项了,只需要用一个预设代替就可以了。另外,预设也可以是插件和其它预设的集合。Babel官方已经对常用的环境做了一些preset包

  • @babel/preset-env
  • @babel/preset-react
  • @babel/preset-typescript
  • @babel/preset-stage-0
  • @babel/preset-stage-1 …

所有的预设也都需要先安装npm包到node_modules。

三、plugin与preset的短名称

插件可以在配置文件里写短名称,如果插件的npm包名称的前缀为 babel-plugin-,可以省略前缀。例如

  module.exports = {
    "presets": [],
    "plugins": ["babel-plugin-transform-decorators-legacy"]
  }

可以写成短名称

  module.exports = {
    "presets": [],
    "plugins": ["transform-decorators-legacy"]
  }

如果npm包名称的前缀带有npm作用域@,例如@org/babel-plugin-xxx,短名称可以写成@org/xxx。

目前Babel7的官方npm包里绝大部分插件已经升级为@babel/plugin-前缀的,这种情况的短名称比较特殊了,绝大部分可以像babel-plugin-那样省略@babel/plugin-。但babel官方并没有给出明确的说明,所以还是推荐用全称。

预设的短名称规则与插件的类似,预设npm包名称的前缀为babel-preset-或作用域@xxx/babel-preset-xxx的可以省略掉babel-preset-。

对于Babel7的官方npm包里绝大部分预设已经升级为@babel/preset-前缀的,这种情况的短名称比较特殊了,绝大部分可以像babel-preset-那样省略@babel/preset-。但babel官方并没有给出明确的说明,例如,@babel/preset-env的短名称就是@babel/env,所以还是推荐用全称。

plugins插件数组和presets预设数组是有顺序要求的。如果两个插件或预设都要处理同一个代码片段,那么会根据插件和预设的顺序来执行。规则如下:

  • 插件比预设先执行
  • 插件执行顺序是插件数组从前向后执行
  • 预设执行顺序是预设数组从后向前执行

四、Babel插件和预设的参数

每个插件是插件数组的一成员项,每个预设是预设数组的一成员项,默认情况下,成员项都是用字符串来表示的,例如"@babel/preset-env"。

如果要给插件或预设设置参数,那么成员项就不能写成字符串了,而要改写成一个数组。数组的第一项是插件或预设的名称字符串,第二项是个对象,该对象用来设置第一项代表的插件或预设的参数。例如给@babel/preset-env设置参数:

  {
    "presets": [
      [
        "@babel/preset-env",
        {
          "useBuiltIns": "entry"
        }
      ]
    ]
  }

小结:

1.这节课我们主要学习了Babel配置文件的配置规则。但在进行开发的时候,我们到底该选择什么插件或预设呢。这部分内容在接下来的教程里学习。

笔记与思考

  1. 网上基本上找不到关于babel的教程,这个算比较好的入门教程了,谢谢博主!

  2. webpack中的babel-loader添加了option配置,项目根部又配置了.babelrc文件,这样是不是转译的时候会同时执行两个配置,导致编译后的文件变得更大?如果两个都会执行,webpack中的option配置和.babelrc文件的配置,哪个的优先级高些?

    1. 因为没这么做过,不一定准确,你可以试一下。 会合并使用配置,相同的项优先使用babel-loader的。

  3. @babel/plugin-transform-runtime 现在不能直接省略@babel/plugin- ,但可以省 plugin-, presets 同理,亲测

发表评论

邮箱地址不会被公开。 必填项已用*标注