Babel抽象语法树(AST)学习

什么是AST?为什么存在?

https://en.wikipedia.org/wiki/Abstract_syntax_tree(维基解释,需翻墙)

大致意思是为了方便编译js脚本,用来表达抽象的语法结构而存在的。。。它不表达语法中的每一个细节,只为了表达结构

什么是Babel?干嘛用的?

Babel官网:https://www.babeljs.cn/docs/

简单来说就是为了做语法转换而存在的,就是将后来出现的更加优秀的语言或者框架,转变为可兼容运行的语言,这里包含且不止js

安装Babel

cnpm install --save-dev babel-loader babel-core babel-preset-env babel-plugin-transform-runtime babel-plugin-istanbul babel-polyfill babel-preset-stage-2 babel-register

Babel工作流程

Parse ==> transform ==>Generate

所以要想完成这几个步骤,babel 提供了几个实用工具(Babylon,babel-traverse,babel-generator

实战问题:如何取出js中引入文件的路径?

例:(路径都是瞎写的!!)

import axios from './123/axios'
import b from '/a'
function square(n) {
  return n * n;
}

这里要取出from后面的文件路径。

先来看一下将这段代码转为AST后是什么:

两个import对象,一个函数对象(最上面的是require函数产生的对象,可忽略),我没有展开树结构,详细的结构可以拷贝上面的代码到这里查看

提取路径代码:

首先生成文件config.ts,内容如上代码,然后去先解析文件,输出ATS,从json中找到文件名。。。

var fs = require('fs');
let babel = require('babel-core');
let t = require('babel-types');
let template = require('@babel/template');
let traverse = require('babel-traverse')
let babylon =require("babylon") ;

// 读取需要修改的源代码内容
var content = fs.readFileSync('./config.ts').toString();
let paramName;
//访问数据的选项
let visitor = {
    //输出导入文件参数
    ImportDeclaration(path) {
        console.log(path.node.source.value);
    },
    //修改函数参数
    FunctionDeclaration(path){
        // console.log( path.node.params[0]);
        const param = path.node.params[0];
        paramName = param.name;
        param.name = "x";
    },
    Identifier(path) {
        if (path.node.name === paramName) {
          path.node.name = "x";
        }
    }
}

// 通过 plugin 转换源代码 parse 出来的AST 抽象语法树,并且返回结果
let result= babel.transform(content, {
   plugins: [
     { visitor}
   ]
 });

 console.warn(`res: ${result.code}`);
 // 把新代码写入新文件.
//  fs.writeFileSync('newRoute.ts', result.code);

使用node执行后输出结果:

./123/axios
/a
res: import axios from './123/axios';
import b from '/a';
function square(x) {
  return x * x;
}

前两行为问题输出结果,后面的打印是修改函数参数后的输出结果,将函数原来的参数 'x' 转变为'n' 

对于没看过babel资料的读者来说,以上代码需要解释的有以下几点:

  1. transform是什么?     还记得上面babel工作的步骤吗?这里一步到位,直接转化过来,返回的是一个对象,包含(code,map,ast)你可以打印输出以下,ast输出为obj

  2. visitor是干嘛的?     这里的visitor是作为访问数据的接口存在的,第一步你打印出的是个对象,你必须通过visitor才能访问到对象内部

  3. visitor里面的函数命名可以随意吗?      不可以!!!!这里面的函数类似css的选择器,是为了选择匹配的参数,这里不多解释,需要补这方面的知识可以去查看babel手册(很全面)

  4. 函数中的path是干嘛用的?   表示两个节点间的连接对象,你可以认为是找到匹配对象入口

传送门:

如何往文件中填加新的数据:https://www.jianshu.com/p/3c495dcbed49

Babel手册(上下):https://github.com/jamiebuilds/babel-handbook/blob/master/translations/zh-Hans/README.md

Babel的transform的参数有哪些:https://www.babeljs.cn/docs/options

查看AST的树结构和json:https://astexplorer.net/

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值