babel深入
参考文章:一口(很长的)气了解 babel、深入Babel,这一篇就够了
核心要点记录
-
babel 总共分为三个阶段
-
解析 @babel/parser
通过
babyIon
(7.x改名为@babel/parser)实现:先 词法分析 把字符串形式的代码解析为 令牌tokens 流 (类似 AST 中节点),再 语法分析 把令牌流转换成 AST -
转换 @babel-traverse
接收到 AST 并通过
@babel-traverse
(维护了 AST 的状态,定义了节点的增删改方法)进行深度优先遍历 -
生成 @babel-generator
将 AST 通过
@babel-generator
进行深度优先遍历,构建字符串,转换成 js 代码
-
-
babel 本身不具有任何转化功能 - 功能全部集成在
plugin
- 语法插件 - 在【解析】阶段解析更多语法
- 转译插件 - 在【转换】阶段进行源码转换
preset
es2015
(单点)和preset
(套餐)的差别:es2015
- 一套规范,包含大概十几二十个转译插件preset
- 插件的集合,不必重复定义、安装
分类:
-
1/2、官方内容,目前包括
env
(最重要),react
,flow
,minify
等 -
2/2、
stage-x
,这里面包含的都是当年最新规范的草案,每年更新低一级的 stage 会包含所有高级 stage 的内容,例如
stage-1
会包含stage-2
,stage-3
的所有内容。Stage 0
- 稻草人: 只是一个想法,经过 TC39 成员提出即可Stage 1
- 提案: 初步尝试Stage 2
- 初稿: 完成初步规范Stage 3
- 候选: 完成规范和浏览器初步实现Stage 4
- 完成: 将被添加到下一年度发布 - 在下一年更新会直接放到env
中,所以没有单独的 stage-4 可供使用
Babel 7.x
变更:淘汰 es201x,删除 stage-x,强推 env (重点)
执行顺序
Plugin
会运行在Preset
之前Plugin
会从前到后顺序执行Preset
的顺序则 刚好相反 (从后向前) - 只要按照规范的时间顺序列出即可,例如:['es2015', 'stage-0']
插件/preset的配置项
带了配置项,自己变成数组;不带配置项,直接列出名字
"presets": [
// 带了配置项,自己变成数组
[
"env", // 第一个元素依然是名字
// 第二个元素是对象,列出配置项
{
"module": false
}
],
// 不带配置项,直接列出名字
"stage-2",
]
env
-
核心目的是通过配置得知目标环境的特点,然后 只做必要的转换
-
配置项 - 如果不写任何配置项,env 等价于
latest
"presets": [ [ "env", { // 常见配置项 targets "targets": { // 考虑所有浏览器的最新2个版本(safari大于等于7.0版本)特性,将必要的代码进行转换 "browsers": ["last 2 versions", "safari >= 7"], // 指定需要支持node 6.10 及以上的版本 "node": "6.10", // 指定需要兼容的浏览器 "ie": "11", "chrome": "58", // 指定只需要处理支持 ES 模块的浏览器 - 浏览器字段被忽略 "esmodules": true, } } ] ]
Babel 7.x
变更
1、preset
变更:淘汰 es201x,删除 stage-x,强推 env (重点)
2、npm package 名称的变化 (重点):把所有 babel-*
重命名为 @babel/*
babel-cli —> @babel/cli;
babel-preset-env —> @babel/preset-env 也可以简写为 @babel/env;
babel-plugin-transform-arrow-functions —> @babel/plugin-transform-arrow-functions 也可以简写为 @babel/transform-arrow-functions
babel 解析语法的内核 babylon
现在重命名为 @babel/parser
3、不再支持低版本 node,要求 nodejs >= 6