前端ast

什么是抽象语法树

抽象语法树 Abstract Syntax Tree 简称AST,是源代码语法结构的一种抽象表示。

比如 const a = 123; ,用ast可以表示为

ast json表示为

{
  "type": "Program",
  "start": 0,
  "end": 14,
  "body": [
    {
      "type": "VariableDeclaration",
      "start": 0,
      "end": 14,
      "declarations": [
        {
          "type": "VariableDeclarator",
          "start": 6,
          "end": 13,
          "id": {
            "type": "Identifier",
            "start": 6,
            "end": 7,
            "name": "a"
          },
          "init": {
            "type": "Literal",
            "start": 10,
            "end": 13,
            "value": 123,
            "raw": "123"
          }
        }
      ],
      "kind": "const"
    }
  ],
  "sourceType": "module"
}

你也可以在ast explorer上试试!

在代码语法的检查、代码风格的检查、格式化、高亮、错误提示、自动补全、实现一套代码适配多端运行等等,即优化变更代码,改变代码结构使达到想要的结构都需要用到ast。

webpack、Lint等这些工具的原理都是通过 js解析器(Js Parser) 把源代码转化为一颗抽象语法树(AST),通过操纵这颗树,我们可以精准的定位到声明语句、赋值语句、运算语句等等,实现对代码的分析、优化、变更等操作。

另外Ast是有规范的,不可能随心所欲的去写,这是里规范: estree

js解析器

想想看 如果你想将源码转为ast,你不会每次都跑去ast explorer上,获取吧。
所以就有专门的工具来获取ast,这就是js解析器。
Js解析器的作用,把Js源码转化为抽象语法树。
Js解析器并不一定都是js写的,有可能是c或者python,如:Js解析器.exe、Js解析器.py

常见的JS解析器有哪些?
acorn、babel/parser、uglify-js、 Esprima、espree等等。这里有更详细的介绍

浏览器中执行js

除了webpack、esLint等这些工具会用到ast外,浏览器引擎(如v8)执行到js的时候 也需要ast

  • 当浏览器引擎拿到 js源码时,会将其转为 ast 树
  • 将构建完毕的 ast 树转为字节码(注意浏览器只会将当前调用栈的代码转为字节码)
  • 字节码转为机器码执行

参考 这里

自己利用ast优化代码

为了兼容低版本浏览器 我们也通常会使用 babel 打包编译我们的代码将 ES6 语法降低版本,
比如箭头函数变成普通函数、将 const、let 声明改成 var 等等,
它们也都是通过 AST 来完成的,只不过实现的过程比较复杂和精致。
不过也都是这三板斧:

import { parse } from "@babel/parser";
import generate from "@babel/generator";
import traverse from "@babel/traverse";

// 将源代码转为ast
const ast = parse("const a = 123;");

// 修改ast
traverse.default(ast, {
  VariableDeclaration(path) {
    if (path.node.kind === "const") {
      path.node.kind = "var";
    }
  },
});

// 将修改后的ast转换回代码
const output = generate.default(ast);
console.log(output.code); // var a = 123;
posted @ 2023-03-29 15:30  丁少华  阅读(116)  评论(0编辑  收藏  举报