一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第15天,点击查看活动详情。
前言
近期在进行一项需求需要追踪项目各文件所使用的依赖,通过现有项目的特征,需要对项目每个 ts 文件进行解析,然后再获取其每个部分,所以需要先解析 ts文件,得到一个 抽象语法树。
抽象语法树(AST)
源代码语法结构的一种抽象表示。主要以树状表示,树上每个节点都是源代码中的一种结构。我们常用的浏览器就是通过将 javaScript 的代码转为抽象语法树,再进行分析等操作。所以抽象语法树是便于程序的分析
- FunctionDeclaration:
- id:
- Identifier:
- name: square
- params [1]
- Identifier
- name: n
- body:
- BlockStatement
- body [1]
- ReturnStatement
- argument
- BinaryExpression
- operator: *
- left
- Identifier
- name: n
- right
- Identifier
- name: n
推荐一个在线 AST 转换网站:astexplorer.net/
AST 使用场景:
- Eslint 进行代码规范检查
- 通过 babel 将译 javascript 语法
- 编辑器的错误提示、代码格式化,代码补全,代码高亮
查阅资料,对于 typescript 其提供了相关的语法解析
var ts = require('typescript');
为了解决我的需求,必须先遍历文件,然后读取文件内的内容,可以使用 fs.readFile 这样就可以读取到 ts 文件的源代码。
对 typescript 的解析,使用 createSourceFile 解析
const astResult = ts.createSourceFile(fileName, data, ts.ScriptTarget.ES5, /*setParentNodes*/ true);
astResult 就是 ts 文件的解析后的抽象语法树,接下来要处理的就是对于遍历树的节点。
class User {
//.....
}
ts 文件都有 class 类型,所以需先进行树节点类型判断是否是 class 类型,如果是的话则继续 class 内属性的节点的查找
if (node.kind === SyntaxKind.ClassDeclaration) {
// 如果是声明为 class 类型,可继续对当前树节点的字节点进行遍历
//;.....
}
if (node.kind === SyntaxKind.Constructor) {
}
SyntaxKind 是个枚举类型,有很多个枚举值,具体可点击查看。
整个过程就很轻松从抽象语法树上得到想要的内容,然后进行一些相关的操作。