babel 与 ast
什么是 babel
Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。
什么是抽象语法树(AST)
在计算机科学中,抽象语法树(Abstract Syntax Tree,AST),或简称语法树(Syntax tree),是源代码语法结构的一种抽象表示。 它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。 之所以说语法是“抽象”的,是因为这里的语法并不会表示出真实语法中出现的每个细节。
对于AST
的相关介绍:
推荐的介绍链接:
Leveling Up One’s Parsing Game With ASTs
中文翻译: https://segmentfault.com/a/1190000038511186
维基百科里的介绍: https://en.wikipedia.org/wiki/Abstract_syntax_tree
babel 的简单使用
相关 api 可以参考文档: https://babeljs.io/docs/en/babel-core#parse
使用 babel 的 API 将代码解析成 ast:
var babel = require("@babel/core");
const code = `const a = 1 + 2;`
// code 解析成 ast
const result = babel.transformSync(code, {ast: true});
console.log(result.ast)
当然 ast 也可以转换成代码:
const { code } = babel.transformFromAstSync(result.ast, { presets: ["minify"], babelrc: false, configFile: false,});
console.log(code)
在这个在线网站,你可以更加直接地看到 code 和 ast 的比较:
https://lihautan.com/babel-ast-explorer
const n = 1
的 ast:
-program:Program{
sourceType:"module" -body:[ -VariableDeclaration { -declarations:[ -VariableDeclarator{ -id:Identifier{ name:"n" } -init:NumericLiteral{ -extra:{ rawValue:1 raw:"1" } value:1 } } ] kind:"const" } ] directives:[]}
babel 插件:
var babel = require("@babel/core");
const code = 'const n = 1';
const output = babel.transformSync(code, {
plugins: [ function myCustomPlugin() {
return {
visitor: {
Identifier(path) {
// 在这个例子里我们将所有变量 `n` 变为 `x` if (path.isIdentifier({ name: 'n' })) {
path.node.name = 'x'; }
},
},
};
},
],});
console.log(output.code);
// const x = 1;
通过 babel 的插件我们可以对代码进行随心所以的修改
关于 visitor
使用的是访问者模式, 在遍历阶段,babel会先进行深度优先遍历来访问AST的每一个节点。你可以为访问指定一个回调函数,然后每当访问某个节点的时候,babel会调用这个函数,并给函数传入当前访问的节点。
现在我们添加另一个函数: NumericLiteral
, 在刚刚的 ast 中我们可以看到 const n = 1
是有 NumericLiteral
此节点的
function myCustomPlugin() {
return {
visitor: {
Identifier(path) {
console.log('identifier');
},
NumericLiteral(path) {
console.log('NumericLiteral');
},
},
};
}
运行 plugin.js
, 打印结果:
Identifier
NumericLiteral
const x = 1;
即在碰到此节点的时候 就会触发插件中对应节点的回调, 关于回调函数的 path 可以在此文档中查看: https://github.com/jamiebuilds/babel-handbook/blob/master/translations/en/plugin-handbook.md#paths
修改表达式
在插件方法 NumericLiteral
上添加操作:
visitor: {
// 省略其他方法 NumericLiteral(path) {
console.log('NumericLiteral');
const newNode = babel.types.binaryExpression('+', babel.types.NumericLiteral(path.node.value), babel.types.NumericLiteral(10));
path.replaceWith(newNode);
path.skip(); // 因为我们新增加了一个 NumericLiteral, 所以插件会检测到, 并且又会触发此回调,造成无限循环 // skip 的作用就是跳过对当前路径子节点的访问 }
}
这里我们新建了一个 binaryExpression, 将 const x = 1
转换为 const x = 1 + 10
这是关于 babel.types
的文件: https://www.babeljs.cn/docs/babel-types
本文代码记录: https://github.com/Grewer/JsDemo/tree/master/babel2AST
参考资料
https://lihautan.com/step-by-step-guide-for-writing-a-babel-transformation/
babel 与 ast的更多相关文章
- 写一个为await自动加上catch的loader逐渐了解AST以及babel
为什么要写这个loader 我们在日常开发中经常用到async await去请求接口,解决异步.可async await语法的缺点就是若await后的Promise抛出错误不能捕获,整段代码区就会卡住 ...
- es6转码器-babel
babel 基本使用 安装转码规则 # ES2015转码规则 $ npm install --save-dev babel-preset-es2015 # react转码规则 $ npm instal ...
- [转] babel的使用
一.配置文件.babelrc .babelrc 文件存放在项目的根目录下. { "presets": [], "plugins": [] } presets 字 ...
- babel那些事儿
从前,一提到新东西,我的反应就是兼容性好不好,如果不能满足产品经理的需求,就还是用保守的方式实现吧.毕竟前端开发是一件很灵活的事,怎么写都行,至于为何会用某种方法,一定是综合考虑兼容性,性能,用户体验 ...
- babel的使用(关于使用async报错的问题)
一.配置文件.babelrc .babelrc 文件存放在项目的根目录下. { "presets": [], "plugins": [] } presets 字 ...
- Babel 入门教程
Babel是一个广泛使用的转码器,可以将ES6代码转为ES5代码,从而在现有环境执行. 这意味着,你可以现在就用 ES6 编写程序,而不用担心现有环境是否支持.下面是一个例子. // 转码前 inpu ...
- Babel 是干什么的
首先babel是干什么的?Babel是一个广泛使用的转码器,可以将ES6代码转为ES5代码,从而在现有环境执行. babel就是为了支持原有的旧的环境. 一.配置文件.babelrc Babel的配置 ...
- 【Babel】293- 初学 Babel 工作原理
戳蓝字「前端技术优选」关注我们哦! 前言 babel Babel 对于前端开发者来说应该是很熟悉了,日常开发中基本上是离不开它的. 已经9102了,我们已经能够熟练地使用 es2015+ 的语法.但是 ...
- 你必须要知道的babel二三事
1. 什么是babel 本文基于的babel版本是7.11.6,本文所有示例github Babel is a toolchain that is mainly used to convert ECM ...
随机推荐
- Guitar Pro小课堂——如何进行消音
在我们弹吉他时,消音技术是必须掌握的一项吉他技能.在我们遇到休止符时.乐曲结束时.乐段,乐句中止时.吉他旋律的分句,呼吸处:变换和弦时的低音(尤其是空弦低音).断奏.弹奏强音时其他空弦被激起的共鸣音( ...
- 苹果电脑下载器Folx有没有自动下载功能
苹果电脑下载器Folx提供了多项自动化任务功能,供用户更好地利用电脑的空闲时间,减少自己直接参与下载的时间,从而提升下载效率. 接下来,小编将重点介绍Folx自动化工作中的任务完成后的自动化工作.自动 ...
- Nginx搭建文件共享服务器
前言 Nginx除了做正反向代理和负载均衡,还能做动静分离服务器,如此便可以当作文件共享服务器使用. 环境 WIN 10 Vmware Workstation 15 Player CentOS Lin ...
- Codeforces Round #656 (Div. 3) 题解
A. Three Pairwise Maximums #构造 题目链接 题意 给定三个正整数\(x,y,z\),要求找出正整数\(a,b,c\),满足\(x=max(a,b), y=max(a,c), ...
- 牛客练习赛68 牛牛的无向图 题解(krusal思想)
题目链接 题目大意 要你查询q 次询问,每次询问给出一个 L ,询问\(\sum_{i=1}^n\sum_{j=i+1}^n[d(i,j)<=L]\).其中 [C] 表示当命题 C 为真的时候为 ...
- Java基础教程——File类、Paths类、Files类
File类 File类在java.io包中.io代表input和output,输入和输出. 代表与平台无关的文件和目录. 可以新建.删除.重命名,但不能访问文件内容. File类里的常量: impor ...
- JVM(三)-java虚拟机类加载机制
概述: 上一篇文章,介绍了java虚拟机的运行时区域,Java虚拟机根据不同的分工,把内存划分为各个不同的区域.在java程序中,最小的运行单元一般都是创建一个对象,然后调用对象的某个 方法.通过上一 ...
- jvm参数与生产配置
堆内存分配:JVM初始分配的内存由-Xms指定,默认是物理内存的1/64JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制:空 ...
- django中的积累
只要继承了model.Model, 就会生成一个新的表,但是,如果在Meta方法中添加abstract=True,就不会产生新的表,而是作为一个基类存放多个表共同拥有的方法和字段等 from djan ...
- fist-第三天冲刺随笔
这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzzcxy/2018SE1 这个作业要求在哪里 https://edu.cnblogs.com/campus/fz ...