作为一个有追求的前端,如果你没有听过Babel的大名,那就真的是out了。不过说实话不太了解Babel的话,其实对日常开发的影响也不大,因为很多脚手架已经配置好了,不用自己折腾。但是如果你想玩转前端工程化这块,这就是绕不过的坎。

babel官方定义为一款​​JavaSscript​​编译器。

Use next generation JavaScript, today.

现在就使用下一代JavaScript语法吧

这里的“下一代”是泛指新的、暂时还不被浏览器广泛支持的,而不是局限于某个确定的版本。

简单来说,浏览器(特别是一些低端浏览器,说你呢IE)对ECMAScript规范的支持是滞后的,新的语法虽然能够给我们带来更好的编程体验,却奈何往往不能不能直接在用户的浏览器运行,所以就需要在浏览器运行这些代码前将其转换成支持的语法,而Babel就是负责这个的,当然它的能力远不止如此,后面我们一一道来。

Babel主要做的就是这几点:

  • 语法转换:将新的语法转换成兼容性更好的旧语法。
  • 特性垫片:通过​​Polyfill​​ 实现目标环境中缺少的特性,将环境的特性差异垫平,说白了还是做兼容。
  • more...
// Babel Input: ES2015 arrow function
[1, 2, 3].map((n) => n + 1);

// Babel Output: ES5 equivalent
[1, 2, 3].map(function(n) {
return n + 1;
});

运行方式

Babel的运行过程分为三个阶段:解析 --- 转换 --- 生成

  1. 解析:解析代码,并生成AST抽象语法树
  2. 转换:将上一步的AST转换成目标环境支持的AST
  3. 生成:根据转换后的AST生成目标代码

不难发现,第二步就是Babel执行的核心操作。但Babel自身是不具备任何转换能力,必须借助一些插件来实现语法的转换。关于插件,后续会详细介绍,这里只需记住,插件赋予了babel强大的能力,没有插件它算个球。

如果想了解具体的转换过程,请阅读从babel讲到AST。

babel解析语法的内核使用的是​​babylon​​​,现在已更名为​​@babel/parser​​。


Babel7

作者在写这篇文章的时候,babel的版本是​​7.10.0​​,​​babel7​​带来了很多新的特性,为了避免给大家造成误导,这里先列出babel7的变化,避免和之前版本的配置混淆。

主要的变化如下:

  • preset:推荐使用 ​​env​​替代​​es201x​​;删除​​stage-x​​ ,因为这些草案中的特性不稳定,维护这些preset会浪费大量精力,所以官方放弃了。如果需要使用可以自己显式的添加对应的插件。
  • npm包名:将所有babel-*更改为@babel/*,更加符合npm命名规范。
  • ​babel-cli​​ -> ​​@babel/cli​​。
  • ​babel-preset-env​​ -> ​​@babel/preset-env​​,简写为 ​​@babel/env​
  • 对低于nodejs6.0不再提供支持。
  • ​@babel/cli​​中不再包含​​@babel/node​​,如要使用需要单独安装。
  • 提供​​babel-upgrade​​帮助开发者从6到7的版本升级。


使用和配置

使用方式

babel的使用场景主要分为两种:命令行和构建工具。

  • 命令行

babel为命令行提供了​​@babel/cli​​工具,支持在命令行直接执行babel命令。

首先,安装必要的包:

npm install --save-dev @babel/core @babel/cli

这里必须要安装​​@babel/core​​,它是babel的核心,它是后续一切的基石,无论哪种方式都必不可少。

安装好在项目中执行​​babel​​命令就可以进行转换了。

babel src --out-dir lib # 将src下的文件处理后输出到lib
  • 构建系统在构建工具中使用才是我们使用babel更常用的方式。这里我们以webpack为例。
    babel提供了一个loader:​​babel-loader​​,使用这个loader我们就能很轻松实现代码转换。
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
options: {
// 配置项
}
}
]
}
  • 运行时(不推荐)babel还提供了运行时环境下的处理,可以在代码运行时,实时进行转换。不过并不推荐这种方式,因为它是在代码运行时实时进行转换,效率较低。
    除了以上方式,还有一些其他的使用方式,详情可以查看​​babel配置​​。