这是我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战
一、编译器原理
什么是编译器?就是把一种语言转换成另一种语言,也就是template(模板字符串)->ast(抽象语法树)->render(渲染函数)。
template模板
<div id='app'>
<h1>{{msg}}</h1>
</div>
在vue中就是在程序运行前执行,因此和运行时关系很小,就是先把template里的代码执行预编译,编译器先把template转换成render函数。好处是以后程序执行的时候不需要携带编译器,vue变小,执行的时候直接执行渲染函数,所以执行就会很快,vue3中把不变的静态节点标记出来,将来在patch发现是静态节点就不用比对,直接对此不再做更新了。
ast抽象语法树
就是js对象,很像vnode虚拟节点dom,里面有当前节点类型,根节点还是组件,是否有子节点,是个树形结构。
render渲染函数
编译器产生的渲染函数是很复杂的,打包模板浏览器,然后起http服务,最终把template-explorer打包之后是一个模板浏览器。
二、Vue3编译过程
获取template
通过app.mount()获取template,template.innerHTML()方式获取。
编译template
进入compileToFunction方法,compile把传入的template字符串编译成render函数,内部实际执行的是baseCompile
- 解析parse:尝试用正则表法是匹配,然后解析字符串template为抽象语法树ast
- 转换transform:解析属性、样式:style、指令v-if等
- 生成generate:把ast进行递归遍历,看到节点就生成对应的节点,最后将ast转换成渲染函数