https:///post/7105032116294909959 持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情
编译器的原理
首先听到编译器这个词,能想到是的从高级语言去开发,但是机器或者是硬件没有办法进行识别,所以需要把这个高级语言转换编译成让它能够识别到的语言,这就是编译的过程
Vue3中的编译器
在Vue3也是有编译的过程,因为在模板<template></template> 中的类似于html 的语法发生了转换。
<template>
<div id='app'>
{{message}}
</div>
</template>
在这过程中发生转换,{{message}} 字符串模板,最终在Vue程序里,真正工作运行的时候,它实际上是一个渲染函数render ,这就是编译器
Vue的编辑器发生在什么时候
- vue打包的时候带不带编译器
当下Vue分为两个版本
-
With Compiler版
如果当前使用的是With Compiler版本,打包之后是包含编译器的,意味着变易发生的时刻是在挂载的时候,就是在mounted中执行
-
runtime.js版
运行时不会编译,它是预编译,打包时webpack会调用Vue-loader 执行编译,将所有的vue文件(SFC),把文件中的template 模板语法的部分转换成render 渲染函数,
好处: 包的体积小,运行时速度快,原因:运行时直接调用渲染函数,不需要再编译模板
由此可以得出 runtime版本运行时执行较快
抽象语法树
template => ast => render
先把模板语法转换成抽象语法树AST,AST再转换成渲染函数,再这过程中还有一些中间操作transform ,因为把模板语法转换成抽象对象,实际是非常粗糙的解析,但还有一些指令、表达式需要解析所以需要一次转换
- 语法树结构
它是和虚拟DOM(Vnode) 的非常相似,注意:它是再编译过程中产生,对于最后程序的运行结果是没有任何的影响,当这个树生成后,它的生命周期已经结束。
import {toDisplayString as _toDisplayString, createVnode as _createVnode,openBlock as _openBlock, createBlock as _createBlock } from 'vue'
export function render(_ctx,_cache){
return (_openBlock(),_createBlock('div',{id:'app'},{
_createVnode()
}))
}
过程
- template获取
app.mount() 获取了template
- 编译template
compile 将传入的模板编译为render函数,实际执行的是baseCompile
- 解析Parse
解析字符串模板为抽象语法树AST
- 转换为TransFrom
解析属性、样式、指令等等
- 生成Generate
将AST对象转换成渲染函数
|