Vue3.2 编译原理总结及补充

107 阅读3分钟

image.png

前言

在前面的几篇文章中,我们把vue3的编译原理进行了详细分析,从template转换成AST到优化AST,再到通过优化过的AST生成渲染函数,每一步都缺一不可,可以说是一环扣一环,但这都是理想状态下的情况,那么今天的这篇文章我们就说一点实际的情况t,假设我们有这样子的一个template,

<h1>hello Vue3</h1>

转换成AST补充

转换的第一步自然是将template转换成AST,它会先去走parseChildren函数,根据不同的规则将template中的层层节点转换成AST

在模板中,先会交给parseElement进行处理,但是由于里面还有文本节点,在处理完开始标记<h1>之后还会再次调用parseChildren中去处理文本,最后由parseTag处理结束标签,最后转换的结果如下,里面有一个children属性,存储的h1标签里的内容。

其他的转换也是类似的流程也是差不多的,基本都是大同小异,比较需要注意的就是attribute的转换。

image.png

AST语义分析补充

语义分析的主要用途是为了能够生成更好的渲染函数,举个例子,比如v-if,只转换成AST树的话,它们只会是以对象的形式存在,那么在v-ifv-else同时存在的话,就不能表达出逻辑性,所以在transform阶段会把他们处理成可以表示逻辑性的对象。

// 转换前大体表示:
 {
      type: NodeTypes.DIRECTIVE,
      name: dirName,
      exp: value && {
        type: NodeTypes.SIMPLE_EXPRESSION,
        content: value.content,
        constType: ConstantTypes.NOT_CONSTANT,
      },
      arg,
      modifiers,
    }
// 转换后大体表示:
{
    consequent,
    alternate: {
        consequent,
        alternate: {
            consequent
        },
    },
  }

在转换后的对象中我们可以清楚的明白它们之间的关系和逻辑性,每个对象中都有一个属性alternate作为当前条件不成立时的候选(else除外)。在生成渲染函数的时候就可以通过这样的对象嵌套关系去生成代码。

生成渲染函数补充

这一部分是根据前面transform转换后的AST去生成代码,这里提供十几个方法用来转换将不同的类型的AST对象转换成代码(服务端渲染还提供了五个,客户端渲染提供了十五个),在生成代码的过程中,这些方法是会互相调用,有时还会进行递归,并且在转换的过程中采用的是深度优先的原则。

至于具体生成代码的方法,如果大家感兴趣的话可以自己到代码仓库中去查看,这些生成代码的方法都有一个同一的,就是在最后都会将自己生成的代码拼接到上下文对象中的Code属性中,到最后会将它变成Function

总结

编译原理作为Vue中重要的一部分,有着十分重要的作用,它是Vue运转的开始,一切的源头,并且编译原理的运用的地方十分广泛,比如ES6转换成ES3这些,统统都是用到了编译原理,虽然内部的实现不一样,但是它们都是异曲同工,都是为了将一种东西转换成另外一种东西,学会了编译原理我们可以得到很多东西,比如其中的算法、思想等等,这些东西都可以是我们提升。

最后,希望各路大佬能够指导和补充,谢谢。