原理浅析
处理流程
babel 是一个编译器
- 解析:将原始代码解析为抽象语法树AST
- 词法分析:原始代码拆分成一个个的Token
- 语法分析:递归遍历Tokens数组,构建AST
- 转换:转换得到的AST,生成新的AST
- 生成:遍历新AST,生成目标代码
参考
核心概念
插件
babel 初始情况不会对代码做任何转换
借助babel-traverse
,插件可以遍历AST并进行增删改操作,进而实现代码转换功能
预设preset
插件本身可能每一个语法都会有独立的插件来做转换
babel 抽象出了preset
来管理一系列插件
核心包
@babel-core
包括:
@babel/parser
:负责将源代码解析成AST@babel/traverse
:向外提供遍历AST节点的能力@babel/generator
:负责根据变换后的AST生成目标代码
@babel/cli
提供在命令行中调用@babel/core
的能力
// 依赖安装
npm i --save-dev @babel/core @babel/cli
// 没有配置任何插件,编译前后的代码完全一样
npx babel src --out-dir dist
@babel/preset
// 依赖安装
npm i --save-dev @babel/preset
// .babelrc
{
"presets": ["@babel/preset-env"]
}
@babel/polyfill
V7.4.0 版本开始,
@babel/polyfill
已经被废弃,单独安装core-js
和regenerator-runtime
模块
core-js
提供了polyfill的核心实现regenerator-runtime
是generator以及async/await的运行时依赖
core-js是一套模块化的JS标准库
// .babelrc
{
"presets": [
["@babel/preset-env", {
"useBuiltIns": "usage",
"corejs": 3
}]
]
}
@babel/runtime & @babel/plugin-transform-runtime
babel 在转换代码的过程中会在模块顶部插入一些帮助函数
class A {}
编译之后
'use strict';
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError('Cannot call a class as a function');
}
}
var A = function A() {
_classCallCheck(this, A);
};
npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime
_classCallCheck2
已经变成从@babel/runtime
中引入
@babel/plugin-transform-runtime
将所有使用到帮助方法的地方,从各自维护一份改为从@babel/runtime
中引入