babel来历
babel英译汉为嘈杂声,别名叫巴别塔(通天塔),传说古时候一群人想建一个通天塔,去天上看看上帝在干什么。上帝于是挥挥手,让这群人说不同的语言,于是他们再也不能顺畅沟通,塔也就建不起来了。
而在web环境中虽然有ECMAScript 作为一套统一的标准,但是同的浏览器对这套规范的实现与支持又是不尽相同。在没有babel的时代,js不同浏览器间的兼容性对于web开发者是个很头痛的问题。
而babel就是要磨平不同浏览器间与不同版本浏览器js规范的支持的差异性出现的。

什么是babel

官方给出的定义为:Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。
从定义可以看出来两个点:
- babel是一个工具集合,确实当代babel被抽象的成各个模块( babel-cli 、babel-core 、babel-node、babel-polyfill、babel-runtime、babel-register等)
- babel可以兼容最新的语法以及通过插件兼容最新的api
babel做了什么


上图是使用babel转译代码的过程,从其中可以看出来babel做了三件事:
- parse(解析):将代码解析成AST语法树
- transform(转换):将解析出来的AST语法降级成低版本的语法的AST
- generator(构建生成):根据AST语法树生成代码
涉及到的原理在后续的深入理解Babel中进行介绍
如何使用Babel
单纯转译一个文件
- 使用mkdir 与 npm init 新建一个干净前端项目
- 安装babel的 cli与core模块

3.书写一个含有箭头函数的js文件(箭头函数es6中刚刚支持)
4.安装箭头函数的转译插件

5.调用babel转译代码,这里可以使用npx 或者 用相对路径调用babel下的可执行文件

6.最终输出

使用配置文件
官方文档中配置分为.babelrc 与 babel.config.js两种
.babelrc
以.babelrc为例(转译let 与 箭头函数),与package同级建立.babelrc文件,去官网找需要转译的插件名并安装同时写入到plugins中


如果需要安装的组件比较多,这样的配置就比较繁琐,因此babel官方又贴心的提供了一个参数presets(预设集,套餐)。操作类似之前。


可以看到,最终输出多了 ‘use strict’,因为是以es6语法套餐为转译基础,转译时候会带上一些可能无关的es6语法特性
babel.config.js

以上,是针对es6语法级别的转换,倘若我们要是写一个es6新增的数组api方法,会发现无法转换,
此时就需要用babel-polyfill进行处理.
Babel做什么,不做什么?
Babel只对不属于ES5的语法做了转换,如:
- for-of
- 箭头函数
- 结构
- 块级作用域
- let/const
但下面情况不作处理:
- 一些内置的全局变量,如:Promise、Symbol、Set、WeakMap
- 对一些Object新增的方法,如: Array.includes、Object.assign
- generactor 函数。
如果原有的Bable做不了这个,则我们需要Babel的一些扩展,babel-polyfill与babel-runtime。
babel-polyfill与babel-runtime
Babel-polyfill
为了能使用Promise、WeakMap等,我们可能需要考虑引入babel-polyfill了。它会检测运行环境是否支持Promise等,如果不支持,会创建全局的Promise等对象或者给Array等新增方法。
Babel-runtime
Babel-runtime也能起到几乎一样的作用,但它跟Babel-polyfill不同的是它不会污染全局作用域。它会提供一个module, 当使用Promise时,它会把这个module的某个对象导出给使用的地方
首先设置一个不支持api的环境,此处以node 0.12.18版本为例,有需要可以查询greennode查看不同node版本对api的支持

然后书写代码运行环境对比
加入polyfill前


加入polyfiil后

