news 2026/6/11 16:09:50

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/6/7 16:45:24

Z-Image-Turbo_UI界面校园动漫少女设计,青春感十足

Z-Image-Turbo_UI界面校园动漫少女设计&#xff0c;青春感十足 1. 引言&#xff1a;用AI打造属于你的二次元校园少女 你是否曾幻想过&#xff0c;自己笔下的动漫角色能从脑海中跃然而出&#xff0c;变成一张张生动的图像&#xff1f;现在&#xff0c;借助 Z-Image-Turbo_UI界…

作者头像 李华
网站建设 2026/6/10 15:28:53

WPF UI 4.0:从零开始打造现代化桌面应用的全新指南

WPF UI 4.0&#xff1a;从零开始打造现代化桌面应用的全新指南 【免费下载链接】wpfui WPF UI在您熟悉和喜爱的WPF框架中提供了流畅的体验。直观的设计、主题、导航和新的沉浸式控件。所有这些都是本地化且毫不费力的。 项目地址: https://gitcode.com/GitHub_Trending/wp/wp…

作者头像 李华
网站建设 2026/6/1 11:05:08

时间序列特征选择利器:tsfresh智能特征筛选完全指南

时间序列特征选择利器&#xff1a;tsfresh智能特征筛选完全指南 【免费下载链接】tsfresh Automatic extraction of relevant features from time series: 项目地址: https://gitcode.com/gh_mirrors/ts/tsfresh 还在为从海量时间序列数据中筛选关键特征而烦恼吗&#x…

作者头像 李华
网站建设 2026/6/10 1:46:27

微信数据解析实战指南:从零掌握PyWxDump

微信数据解析实战指南&#xff1a;从零掌握PyWxDump 【免费下载链接】PyWxDump 获取微信账号信息(昵称/账号/手机/邮箱/数据库密钥/wxid)&#xff1b;PC微信数据库读取、解密脚本&#xff1b;聊天记录查看工具&#xff1b;聊天记录导出为html(包含语音图片)。支持多账户信息获取…

作者头像 李华
网站建设 2026/6/10 20:39:06

Open-AutoGLM部署技巧:快速获取设备IP地址的两种方法

Open-AutoGLM部署技巧&#xff1a;快速获取设备IP地址的两种方法 Open-AutoGLM – 智谱开源的手机端AI Agent框架&#xff0c;为开发者提供了一种全新的自动化交互方式。它结合视觉语言模型与安卓系统底层控制能力&#xff0c;让自然语言指令可以直接转化为手机操作行为。 Au…

作者头像 李华
网站建设 2026/6/6 1:57:01

5分钟部署Fun-ASR,钉钉通义语音识别系统一键搭建

5分钟部署Fun-ASR&#xff0c;钉钉通义语音识别系统一键搭建 你是否还在为会议录音转文字效率低而头疼&#xff1f; 有没有一种方式&#xff0c;能像用Word一样简单地把一段音频“变成”可编辑的文字&#xff1f; 更重要的是——整个过程数据不离本地&#xff0c;安全可控。 …

作者头像 李华