【vue3源码轻松学系列三】编译器

简介

什么是编译器

编译器其实只是一段程序,它用来将"一种语言 A"翻译成"另外一种语言 B"。其中,语言 A 通常叫作源代码(source code),语言 B 通常叫作目标代码(object code 或 target code)。编译器将源代码翻译为目标代码的过程叫作编译(compile)。完整的编译过程通常包含词法分析、语法分析、语义分析、中间代码生成、优化、目标代码生成等步骤。

编译器、解析器、渲染器三者对比

在 Vue 3 中,编译器、解释器和渲染器是三个不同的概念,它们共同负责将 Vue 模板转换为最终的 DOM 元素。

编译器

编译器负责将 Vue 模板转换为 JavaScript 代码。这个过程发生在浏览器中,在页面加载之前。编译器会将模板中的指令和表达式解析为 JavaScript 函数,并生成一个虚拟 DOM (VDOM)。

解释器

解释器负责将 VDOM 转换为真实 DOM。这个过程发生在浏览器中,在页面加载之后。解释器会遍历 VDOM,并为每个节点创建相应的真实 DOM 元素。

渲染器

渲染器负责将真实 DOM 元素更新到页面上。这个过程发生在浏览器中,每次 Vue 组件的状态发生变化时都会触发。渲染器会比较新的 VDOM 和旧的 VDOM,并只更新那些发生变化的 DOM 元素。

三者的区别

编译器、解释器和渲染器之间主要的区别如下:

  • 编译器:将模板转换为 JavaScript 代码。
  • 解释器:将 VDOM 转换为真实 DOM。
  • 渲染器:将真实 DOM 元素更新到页面上。

vue3中编译器原理与过程

可以看到,Vue.js 模板编译器的目标代码其实就是渲染函数。

详细步骤:

  1. 词法分析:将模板字符串转换为 AST(抽象语法树)。
  2. 优化:对 AST 进行优化,例如静态提升、常量折叠等。
  3. 代码生成:根据优化后的 AST 生成 JavaScript 渲染函数。

词法分析

词法分析阶段负责将模板字符串转换为 AST。AST 是一个树形结构,每个节点代表模板中的一个元素或表达式。

Vue3 中的词法分析使用了一种叫做 有限状态机 的技术。有限状态机是一种可以识别特定模式的数学模型。Vue3 中的有限状态机定义了各种状态,每个状态代表模板中的一种语法结构。

例如,当词法分析器遇到 <div> 标签时,它会进入 元素开始 状态。在这个状态下,词法分析器会继续扫描模板,直到遇到 </div> 标签。当遇到 </div> 标签时,词法分析器会退出 元素开始 状态,并进入 元素结束 状态。

词法分析阶段的最终输出是一个 AST。AST 中的每个节点都包含了一些信息,例如节点类型、节点名称、节点属性等。

优化

优化阶段负责对 AST 进行优化,例如静态提升、常量折叠等。

静态提升是指将不会发生变化的节点提升到更高的层级。例如,如果一个节点的文本内容是固定的,那么就可以将该节点提升到根节点。这样可以减少渲染时的开销。

常量折叠 是指将常量表达式折叠成常量值。例如,如果一个节点的表达式是 1 + 2,那么就可以将该表达式折叠成 3。这样可以减少渲染时的计算量。

代码生成

代码生成阶段负责根据优化后的 AST 生成 JavaScript 渲染函数。

渲染函数是一个 JavaScript 函数,它负责将 VDOM 转换为真实 DOM。

Vue3 中的代码生成使用了一种叫做 模板引擎的技术。模板引擎是一种可以根据模板生成 JavaScript 代码的工具。

Vue3 中的模板引擎使用了一种叫做 指令 的技术。指令是一种特殊的 HTML 属性,它可以用来控制 DOM 元素的行为。

例如,v-if 指令可以用来控制 DOM 元素是否显示。

代码生成阶段的最终输出是一个 JavaScript 渲染函数。该函数可以被 Vue 实例调用,用于将模板渲染到页面上。

总结

Vue3 中的编译器采用了全新的设计,与 Vue2 中的编译器相比有很大的不同。Vue3 中的编译器可以分为三个阶段:词法分析、优化和代码生成。

词法分析阶段负责将模板字符串转换为 AST。

优化阶段负责对 AST 进行优化,例如静态提升、常量折叠等。

代码生成阶段负责根据优化后的 AST 生成 JavaScript 渲染函数。

相关推荐
533_29 分钟前
[vue] 深拷贝 lodash cloneDeep
前端·javascript·vue.js
ZBY520311 小时前
【Vue】 npm install amap-js-api-loader指南
javascript·vue.js·npm
计算机毕设指导61 小时前
基于 SpringBoot 的作业管理系统【附源码】
java·vue.js·spring boot·后端·mysql·spring·intellij-idea
木子02043 小时前
前端VUE项目启动方式
前端·javascript·vue.js
GISer_Jing3 小时前
React核心功能详解(一)
前端·react.js·前端框架
运维-大白同学4 小时前
将django+vue项目发布部署到服务器
服务器·vue.js·django
星星会笑滴5 小时前
vue+node+Express+xlsx+emements-plus实现导入excel,并且将数据保存到数据库
vue.js·excel·express
Backstroke fish5 小时前
Token刷新机制
前端·javascript·vue.js·typescript·vue
临枫5415 小时前
Nuxt3封装网络请求 useFetch & $fetch
前端·javascript·vue.js·typescript
RAY_CHEN.5 小时前
vue3 pinia 中actions修改状态不生效
vue.js·typescript·npm