Babel: 实际上就是一个JavaScript的编译器,用来将ES6代码转换为浏览器或者其他环境支持的代码
Babel 工作流程:
大致分三步:
- Parser 解析源文件
- Transform 转换
- Generator 生成新文件
引擎:acorn
如何转化: 通过插件,Babel给每个新语法提供插件,在Babel里面配置什么插件,就转化对应的语法。插件命名形式:@babel/plugin-xxx
Babel组成:
@babel/preset-env
最常用,包含大部分ES6语法,如果源码使用了不包含在@babel/preset-env中的语法,会报错,可以根据报错手动在plugis中添加。
targets: 非常重要的参数,通过targets属性,让Babel知道目标环境,从而只转义环境不支持的语法。如果不配置的话会默认转义所有ES6语法。
@babel/polyfill (polyfill:垫片)
core-js
Babel将ES6的标准分为 syntax 和 built-in 两种类型。
syntax 是语法,像 const ,=>之类, 此类会默认被Babel转义。
built-in 可以通过改写覆盖的语法,像includes,Promise等。
Babel 默认只转义syntax类型,built-in类型需要通过@babel/polyfill 来转义。@babel/polyfill 实现的原理就是覆盖那些ES6新增的built-in。
Babel在7.4.0 废弃@babel/polyfill,通过core-js替代。
core-js:
配置useBuiltIns属性:'entry','usage',false。 默认值是false,不注入垫片
'entry' 只需要在项目入口处,导入core-js。编译后Babel会把目标环境不支持的built-in一股脑都注入进来。(但是这完全没必要,会白白增加包的大小)
'usage' Babel会在编译源码过程中根据built-in使用情况来选择注入相应的实现。
@babel/plugin-transform-runtime
在编译的过程中,对于 built-in 类型的语法通过 require("core-js/modules/xxxx") polyfill 的方式来兼容,对于 syntax 类型的语法在转译的过程会在当前模块中注入类似 _classCallCheck 和 _defineProperty 的 helper 函数来实现兼容。对于一个模块而言,可能还好,但对于项目中肯定是很多模块,每个模块模块都注入这些 helper 函数,势必会造成代码量变得很大。
而 @babel/plugin-transform-runtime 就是为了复用这些 helper 函数,缩小代码体积而生的。当然除此之外,它还能为编译后的代码提供一个沙箱环境,避免全局污染。
参考:前端科普系列-Babel:把 ES6 送上天的通天塔 - 知乎