开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第40天,点击查看活动详情
前言
在封装 ts-lint的插件校验语法时,需要对所有ts 文件进行语法解析,所以就需要追踪项目所有的文件以及所使用的依赖。因为使用的是 TS 进行开发,所以通过现有项目的特征,对于每个 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
使用场景:
- 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 是个枚举类型,有很多个枚举值,具体可点击查看。
- 推荐一个在线 AST 转换网站:astexplorer.net/
整个过程就很轻松从抽象语法树上得到想要的内容,然后进行一些相关的操作。