AST语法树

0 阅读4分钟

AST是什么

AST 是 Abstract Syntax Tree抽象语法树)的缩写。
它是计算机科学中用于表示源代码结构的一种树状数据结构。在前端开发中,AST 是现代工程化工具(如 Babel、TypeScript、ESLint、Prettier、Webpack/Vite 等)的核心基石

AST是怎样的结构

const a = 1 + 2;

AST:计算机将这串字符解析后,生成的树形对象。它剥离了无关细节(如空格、分号、括号),只保留代码的逻辑结构

对应的 AST 结构大致如下:

{
  "type": "Program",
  "body": [
    {
      "type": "VariableDeclaration",
      "kind": "const",
      "declarations": [
        {
          "type": "VariableDeclarator",
          "id": { "type": "Identifier", "name": "a" },
          "init": {
            "type": "BinaryExpression",
            "operator": "+",
            "left": { "type": "Literal", "value": 1 },
            "right": { "type": "Literal", "value": 2 }
          }
        }
      ]
    }
  ]
}

一旦变成这样,计算机就能精准地知道:a 是个变量,+ 是加法运算,左边是 1,右边是 2。

开发阶段如何使用AST

在开发阶段,也经常使用到AST语法树.

  1. 使用现有工具(Babel, ESLint, Prettier)的插件系统,通过编写简单的 Visitor 模式代码来操作 AST。

    1.1 ESLint 规则 (代码规范) 当团队有特殊的业务规范,而现有规则无法满足时(例如:“禁止在 Redux reducer 中直接修改 state”或“特定组件必须传入 prop X”)。

    • 原理:ESLint 遍历 AST,当你定义的 Selector 匹配到特定节点时,执行回调函数进行报错或自动修复。
    • 工具eslint@typescript-eslint/parser

    1.2 自动化重构 (Codemod)

    当需要大规模修改代码时(例如:升级 React 版本、重命名整个项目的 API、将 Class 组件转为 Hooks)。

    • 原理:编写脚本批量读取文件 -> 解析为 AST -> 查找并修改特定节点 -> 写回文件。
    • 工具jscodeshift (Facebook 开源,基于 Recast),babel-plugin

    1.3 构建自定义 Babel 插件 (语法转换)

    当需要支持非标准的语法糖,或者在编译阶段注入特定逻辑(如自动埋点、权限校验代码注入)。

    • 原理:编写 Babel Plugin,利用 visitor 对象拦截特定类型的节点(如 CallExpression),修改其参数或替换整个节点。
    • 工具@babel/core@babel/types@babel/traverse
  2. 直接使用解析器(Parser)和生成器(Generator)库,手动完成“解析 -> 转换 -> 生成”的全流程,用于构建自定义工具或 Codemod。

网页渲染过程如何使用到AST

当浏览器从服务器接收到 HTML 字符串后,在将其渲染到屏幕(Paint)之前,浏览器内核(如 Chrome 的 Blink、Safari 的 WebKit)必须经历一个核心步骤:解析(Parsing) 。在这个步骤中,浏览器会将 HTML 字符串转换为 DOM Tree(文档对象模型树)

这个 DOM Tree 本质上就是一种 AST(抽象语法树)。

浏览器渲染页面的标准流水线如下:

  1. 接收字节 (Bytes) :网络传输完成的 HTML 二进制数据。

  2. 解码 (Decoding) :将字节转换为字符(UTF-8 等)。

  3. 标记化 (Tokenization) :词法分析。将字符流切分成一个个“令牌”(Tokens),例如 <div> 是一个开始标签令牌,hello 是文本令牌,</div> 是结束标签令牌。

  4. 构建树 (Tree Construction) —— 这里就是 AST 生成的时刻****:

    • 浏览器根据 Tokens 和 HTML 语法规则,构建出一棵层级分明的树状结构。
    • 这棵树就是 DOM Tree
    • 这就是 AST:它去除了空格、换行等无关格式细节,只保留了标签的嵌套关系、属性和文本内容。
  5. 样式计算 (Style Calculation) :结合 CSS 生成 CSSOM Tree (CSS AST语法树)。

  6. 布局 (Layout/Reflow) :结合 DOM 和 CSSOM 计算每个元素的位置和大小, DOM TREE和CSSOM TREE合并起来生成RENDER TREE。

  7. 绘制 (Paint) :将像素画到屏幕上 (知识点:回流和重绘)。

webpack打包的时候如何使用到AST

构建打包时 (Build/CI 阶段 - 分钟级响应)

这是 AST 最密集工作的阶段。当你运行 npm run build 或在 CI/CD 流水线中时。

  • 语法转译 (Babel / SWC / TypeScript Compiler)

    • 时间:构建开始,处理每个源文件时。

    • 作用

      1. Parse: 将 TSX/ES6+ 代码转为 AST。
      2. Transform: 遍历 AST,把新语法节点替换为旧语法节点(如把 class 转为 function,把 JSX 转为 React.createElement),擦除类型信息。
      3. Generate: 输出兼容性好的 JS 代码。
  • 依赖分析与 Tree Shaking (Webpack / Vite / Rollup)

    • 时间:模块 bundling 阶段。
    • 作用:构建工具解析所有文件的 AST,建立依赖图。如果发现某个导出的函数在 AST 中没有任何“引用节点”,则判定为死代码(Dead Code),直接将其从最终包中剔除。
  • CSS 预处理 (Sass/Less/PostCSS)

    • 时间:样式处理阶段。
    • 作用:将 SCSS 代码解析为 AST,处理变量替换、嵌套展开、Mixin 插入,最后生成 CSS 字符串。