当前位置: 首页 > news >正文

Vue3底层架构——编译器

编译器是什么意思呢?和我们之前讲过的响应式系统有什么关联呢?

编译器只会生成“访问响应式数据的代码”,执行收集依赖在运行时。

编译 .vue 文件 -> render -> 访问 _ctx.count -> proxy.set -> track

而本文我们着重讲讲编译这个过程。

一、Vue 编译器整体架构

Vue3 把编译器拆分为三个部分:

@vue/compiler-sfc   → 处理 .vue 文件
@vue/compiler-dom   → DOM 平台相关编译
@vue/compiler-core  → 核心编译逻辑(平台无关)

90% 的“原理”,都在 compiler-core

核心目标是把 template 转成“尽量少 diff 的 render 函数”

最终产物不是字符串,而是:

二、编译流水线

Vue 编译是一个​标准三段式编译器​:

学过 babel 的同学可以发现,这个过程非常像 babel 。

Template↓ parse
Template AST↓ transform
JavaScript AST(增强)↓ generate
render function

源码入口(compiler-core):

baseCompile(template, options)

三、第一阶段:parse(模板 → AST)

3.1 AST 节点结构

interface Node {type: NodeTypesloc
}

常见节点类型:

enum NodeTypes {ROOT,ELEMENT,TEXT,INTERPOLATION,SIMPLE_EXPRESSION,ATTRIBUTE,DIRECTIVE
}

3.2 parse 的本质

依次遍历解析每一个节点,把 template 字符串解析成一棵 AST

示例:

<div>{{ count }}</div>

生成 AST(简化):

ROOT└─ ELEMENT(div)└─ INTERPOLATION└─ SIMPLE_EXPRESSION(count)

四、第二阶段:transform(AST → 优化 AST)

transform 阶段做的不是“改结构”,而是:给 AST 打“运行时优化标记”

4.1 transform 的执行模型

function transform(root, options) {traverseNode(root, context)
}

遍历 AST,对每个节点:

  • 执行 nodeTransforms
  • 收集依赖
  • 标记 PatchFlag
  • 构建 BlockTree

4.2 transformContext

interface TransformContext {helperscomponentsdirectivescurrentNodeparent
}

transform 不是“纯函数”,而是有上下文的编译过程

4.3 表达式分析

{{ count }}

会被转成:

toDisplayString(_ctx.count)

并且:

  • 标记该节点 依赖响应式数据
  • 未来会生成 PatchFlag

4.4 PatchFlag 的来源

PatchFlag 是在 transform 阶段生成的:

PatchFlags.TEXT
PatchFlags.CLASS
PatchFlags.PROPS
PatchFlags.STYLE

例如:

<div>{{ count }}</div>

最终标记:

1 /* TEXT */

该魔法注释表示:这个节点只需要 diff 文本

4.5 Block Tree

openBlock()
createElementBlock(...)

Block 的作用:收集所有“动态子节点”

transform 阶段会判断:

  • 哪些节点是静态的
  • 哪些是动态的

动态的才进入 block:

block.children.push(node)

diff 时只遍历 block,不全树 diff

五、第三阶段:generate(AST → render 函数)

5.1 generate 的目标

输出一个 JS 函数 AST,最后 stringify:

function render(_ctx, _cache) {return ...
}

5.2 helper 的注入机制

transform 阶段收集:

context.helpers.add(CREATE_ELEMENT_VNODE)

generate 时生成:

import { createElementVNode } from "vue"

5.3 生成代码示例

<div class="a">{{ count }}</div>

生成 render:

function render(_ctx, _cache) {return openBlock(), createElementBlock("div",{ class: "a" },toDisplayString(_ctx.count),1)
}

六、compiler-sfc:.vue 文件是怎么来的?

<template />
<script setup />
<style scoped />

compiler-sfc 做的事:

  • 拆块
  • script setup → 普通 setup
  • CSS scopeId 注入
  • template 交给 compiler-dom

七、为什么 template 性能比 JSX 更稳定?

一句话总结:JSX 直接写 render 函数,绕过了 compiler(绕过了 PatchFlag、BlockTree、精准 diff)。

http://www.jsqmd.com/news/275455/

相关文章:

  • 电脑怎么通过一个网卡访问多个网段?一招解决
  • 【计算机毕业设计案例】人工智能基于python-CNN深度学习的番茄叶病害识别
  • 电影解说详细教程:从「一条视频」到「持续更新」
  • 终于有人把数字化讲清楚了 - 智慧园区
  • 对话管理在智能车载系统中的应用实践
  • 【Da】媒体、快编面板
  • 【Da】媒体、快编面板
  • 【计算机毕业设计案例】卷神经网络基于python-CNN深度学习训练识别不同颜色的鞋子
  • Sublime 配置
  • 2026年TikTok广告代理商推荐:应对算法迭代与合规风控的优选服务商
  • 极限科技荣膺 2025 金猿奖 — “年度国产化优秀代表厂商”,自主可控搜索方案 Easysearch 获行业高度认可
  • 20260120 之所思 - 人生如梦
  • springboot151基于javaweb的线上鲜花商城管理系统的设计与实现
  • 教育体系的变革:编程作为基础技能
  • Zipkin Brave使用
  • Zipkin Brave使用
  • 智能运维AI平台架构设计与服务网格(Istio)整合实践:架构师详解
  • 深度学习的核心求梯度就是多维函数求导数
  • 2026必备!专科生毕业论文痛点全解TOP9 AI论文网站
  • 深度学习毕设选题推荐:基于python-CNN机器学习的乐器识别
  • 基于微信小程序的考研论坛【源码+文档+调试】
  • 俺的第一篇部落格!
  • 从设计到营销,先知AI解锁男装行业增长新密码
  • 这两个专注于Skills的开源项目,正在GitHub上引发关注
  • 掌握核心方法论,打造高质量业务仪表板
  • 谷歌新发现:DeepSeek推理分裂出多重人格,左右脑互搏越来越聪明
  • 【课程设计/毕业设计】机器学习基于python-CNN深度学习的乐器识别
  • 【课程设计/毕业设计】机器学习基于python-CNN深度学习识别是否发生火灾
  • 超声波气象站:无探头零磨损,开启无械感监测新纪元
  • 南京下雪啦~