news 2026/4/23 15:50:37

Vue3底层架构——编译器

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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: NodeTypes loc }

常见节点类型:

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 { helpers components directives currentNode parent }

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)。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/22 20:22:25

中小企业如何落地AI绘图?Z-Image开源镜像部署实战案例

中小企业如何落地AI绘图&#xff1f;Z-Image开源镜像部署实战案例 1. 为什么中小企业需要自己的AI绘图能力&#xff1f; 在内容为王的时代&#xff0c;视觉素材成了品牌传播的核心。电商主图、社交媒体配图、宣传海报……这些原本依赖设计师的产出&#xff0c;现在正被AI绘图…

作者头像 李华
网站建设 2026/4/23 7:55:28

支持MP3/WAV/FLAC!FSMN VAD多格式音频处理实战

支持MP3/WAV/FLAC&#xff01;FSMN VAD多格式音频处理实战 1. FSMN VAD是什么&#xff1f;为什么它值得你关注 1.1 语音活动检测&#xff1a;被忽视的关键环节 在语音识别、会议转录、电话质检等应用中&#xff0c;我们常常只关注“说了什么”&#xff0c;却忽略了“什么时候…

作者头像 李华
网站建设 2026/4/23 7:50:38

亲测科哥UNet抠图WebUI,人像/产品图批量处理效果惊艳

亲测科哥UNet抠图WebUI&#xff0c;人像/产品图批量处理效果惊艳 1. 上手即用的AI抠图神器 最近在做一批电商产品图和人像素材的后期处理&#xff0c;手动抠图效率太低&#xff0c;边缘细节也难把控。偶然发现CSDN星图上有一款名为 cv_unet_image-matting图像抠图 webui二次开…

作者头像 李华
网站建设 2026/4/23 7:54:12

Qwen3-Embedding-0.6B vs BGE实战对比:多语言检索性能谁更强?部署案例详解

Qwen3-Embedding-0.6B vs BGE实战对比&#xff1a;多语言检索性能谁更强&#xff1f;部署案例详解 在当前AI驱动的信息检索场景中&#xff0c;文本嵌入模型的性能直接决定了搜索、推荐和语义理解系统的质量。随着多语言内容需求的增长&#xff0c;如何选择一个高效、准确且易于…

作者头像 李华
网站建设 2026/4/22 18:12:46

SGLang-v0.5.6部署教程:3步实现GPU高吞吐推理实战

SGLang-v0.5.6部署教程&#xff1a;3步实现GPU高吞吐推理实战 SGLang-v0.5.6 是当前在大模型推理优化领域备受关注的一个版本。它不仅提升了多GPU环境下的调度效率&#xff0c;还在KV缓存管理和结构化输出方面带来了显著改进。对于希望在生产环境中实现高吞吐、低延迟推理的服…

作者头像 李华
网站建设 2026/4/23 7:52:25

Qwen-Image-Edit-2511阴影方向还原好,光影一致性出色

Qwen-Image-Edit-2511阴影方向还原好&#xff0c;光影一致性出色 你有没有遇到过这样的尴尬&#xff1a;改完一张产品图的LOGO&#xff0c;却发现新文字的阴影方向和原图完全对不上&#xff1f;左边打光的瓶子上&#xff0c;AI生成的文字却带着右边的投影&#xff0c;一眼假。…

作者头像 李华