mini-vue3实现记录-简易版编译器

248 阅读2分钟

对于vuejs模板编译器来说,源代码就是组件的模板template,而目标代码是能够在浏览器平台上运行的js代码,或其他拥有js运行时的平台代码。

对于vuejs模板编译,编译器首先会对模板进行词法分析和语法分析(parse),得到模板AST。然后将模板AST转化(transform)成JavaScriptAST,最后将JavaScriptAST转化为js代码,即渲染函数。

parse部分

parse部分实现的是将模板template转化为模板AST,对于template,包含三种类型:element类型、text类型和插值类型,这里不做具体实现的分析, 我们谈一下parser是如何对模板进行切割,依据的是什么规则。实际上,parser的解析就是一个有限状态自动机,下面以一个例子进行解析

图片.png

  1. 从初始状态开始进行解析,检测到以<a-z开头,说明为element类型,进行parseElement, 然后解析tag,进行parseTag
  2. 继续往下解析(类似树往下遍历),解析其children,回到初始状态,判断为text类型,进行parseText,无children,解析完毕,回到初始状态
  3. 在同一树层继续解析,遇到插值类型,进行插值类型解析,解析完毕,无children,达到end,回到初始状态
  4. 解析结束tag,解析完毕,回到初始状态,模板ast构建完成

图片.png

transform

transform实际上是用于完成AST的转换工作。当我们需要对AST的一些节点进行修改时,我们首先需要进行遍历,然后再编写对应的修改函数。
然而长此以往,transform的代码充斥各种各样的处理节点函数,这样transform函数会非常臃肿,我们可以利用插件化体系的结构解决这一问题,也就是将处理节点的回调函数传给transform, 然后逐个进行注册

执行顺序工作流

对于我们目前的体系结构,我们采用的是一种顺序执行,从根节点开始的工作流,如果我们需要根据子节点的状态对当前节点进行转换,那么目前的工作流是无法做到的,所以我们需要重新设计一个工作流.
对于每个节点的处理,我们需要有一个进入状态和退出状态,顺序执行完进入状态函数后再反向执行退出的回调函数。 详细代码请见( github.com/4noth1ng/my… )