zhangdizhangdi

编译器

Vue 的模板(template)语法,需要被编译成 渲染函数(render function),最后再由 runtime 渲染成真实 DOM。

主要文件夹:

  • compiler-core
  • compiler-dom
  • compiler-sfc
  • compiler-ssr

@vue/compiler-sfc 👉 专门负责 SFC 文件 的解析(.vue 文件,包含 <script> <template> <style> 等),它会把一个完整的 SFC 拆分成 descriptor,再分别编译 script / template / style。

@vue/compiler-dom 👉 只负责 编译 template → render 函数(DOM 平台专用),它不认识 <script>/ <style>,也不懂 .vue 文件。

流程:

  • Parse:把字符串解析成 AST
  • Transform:遍历 AST,做语法糖消解 & 代码优化(v-if / v-for / slot / v-model …)
  • Generate:把 AST 转成 JS 代码(render 函数)
重点:
  • AST 结构
  • 指令(v-if、v-for、v-bind 等)如何在 Transform 阶段转成代码
  • 编译时优化(PatchFlag、静态提升)

parse(解析模板 → AST)

Vue 内部在 @vue/compiler-core/src/parse.ts 里实现。

模板先被 tokenizer + parser 转成 AST(抽象语法树)。

结果类似:

json
{
  "type": "Root",
  "children": [
    {
      "type": "Element",
      "tag": "div",
      "props": [{ "name": "id", "value": "app" }],
      "children": [ ... ]
    }
  ]
}

transform(AST 转换)

遍历 AST,套用不同的 transform 插件。
这里会做「指令语法糖」到「低阶函数调用」的映射。

常见 transform:

  • transformElement →
    生成 createElementVNode
  • transformText → 文本节点
  • transformExpression → 处理 {{ msg }}
  • transformBind → v-bind
  • transformOn → v-on
  • transformFor、transformIf → v-for/v-if

generate(AST → 代码字符串)

把 AST 转成 render 函数字符串,包含 imports(如 openBlock, createElementBlock)。

见 @vue/compiler-core/src/codegen.ts

compiler-sfc

compiler-sfc 是 Vue 的单文件组件(Single File Component, SFC)编译器,负责将 .vue 文件编译成可以在浏览器中运行的 JavaScript 代码。

  1. 解析(Parse):将 .vue 文件解析成结构化的描述对象
    • 拆出 descriptor:包含 template/script/style/customBlocks
  2. 编译脚本(Compile Script):处理 <script><script setup>
    • 普通 <script>:直接作为 JS
    • <script setup>:需要 transform,把组合式 API 语法糖转为普通的 setup()
  3. 编译模板(Compile Template):将 <template> 部分编译成渲染函数
    • 调用 compileTemplate,走「parse → transform → generate」
    • 得到 render 函数
  4. 编译样式(Compile Style):处理 <style> 部分,包括作用域样式
    • 普通 CSS 直接抽出
    • scoped 会生成额外的哈希,编译时在每个 DOM 节点加上属性选择器(如 data-v-xxxx),实现样式作用域
  5. 整合
    • 把 template 编译的 render 函数,和 script 部分的逻辑,拼成最终的组件。

@vitejs/plugin-vue

工作流程:

  • .vue 文件请求
  • Vite 开发服务器
  • @vitejs/plugin-vue 拦截处理
  • 调用 @vue/compiler-sfc
    • parse
    • compileScript
    • compileTemplate
    • compileStyle
  • 生成可执行的 JavaScript 模块
  • 浏览器加载执行