看不懂来打我,vue3如何将template编译成render函数

  • 看不懂来打我,vue3如何将template编译成render函数已关闭评论
  • 97 次浏览
  • A+
所属分类:Web前端
摘要

在之前的 通过debug搞清楚.vue文件怎么变成.js文件 文章中我们讲过了vue文件是如何编译成js文件,通过那篇文章我们知道了,template编译为render函数底层就是调用了@vue/compiler-sfc包暴露出来的compileTemplate函数。由于文章篇幅有限,我们没有去深入探索compileTemplate函数是如何将template模块编译为render函数,在这篇文章中我们来了解一下。


前言

在之前的 通过debug搞清楚.vue文件怎么变成.js文件 文章中我们讲过了vue文件是如何编译成js文件,通过那篇文章我们知道了,template编译为render函数底层就是调用了@vue/compiler-sfc包暴露出来的compileTemplate函数。由于文章篇幅有限,我们没有去深入探索compileTemplate函数是如何将template模块编译为render函数,在这篇文章中我们来了解一下。

@vue下面的几个包

先来介绍一下本文中涉及到vue下的几个包,分别是:@vue/compiler-sfc@vue/compiler-dom@vue/compiler-core

  • @vue/compiler-sfc:用于编译vue的SFC文件,这个包依赖vue下的其他包,比如@vue/compiler-dom@vue/compiler-core。这个包一般是给vue-loader 和 @vitejs/plugin-vue使用的。

  • @vue/compiler-dom:这个包专注于浏览器端的编译,处理浏览器dom相关的逻辑都在这里面。

  • @vue/compiler-core:从名字你也能看出来这个包是vue编译部分的核心,提供了通用的编译逻辑,不管是浏览器端还是服务端编译最终都会走到这个包里面来。

先来看个流程图

先来看一下我画的template模块编译为render函数这一过程的流程图,让你对整个流程有个大概的印象,后面的内容看着就不费劲了。如下图:
看不懂来打我,vue3如何将template编译成render函数

从上面的流程图可以看到整个流程可以分为7步:

  • 执行@vue/compiler-sfc包的compileTemplate函数,里面会调用同一个包的doCompileTemplate函数。

  • 执行@vue/compiler-sfc包的doCompileTemplate函数,里面会调用@vue/compiler-dom包中的compile函数。

  • 执行@vue/compiler-dom包中的compile函数,里面会对options进行了扩展,塞了一些处理dom的转换函数进去。分别塞到了options.nodeTransforms数组和options.directiveTransforms对象中。然后以扩展后的options去调用@vue/compiler-core包的baseCompile函数。

  • 执行@vue/compiler-core包的baseCompile函数,在这个函数中主要分为4部分。第一部分为检查传入的source是不是html字符串,如果是就调用同一个包下的baseParse函数生成模版AST抽象语法树。否则就直接使用传入的模版AST抽象语法树。此时node节点中还有v-forv-model等指令。这里的模版AST抽象语法树结构和template模块中的代码结构是一模一样的,所以说模版AST抽象语法树就是对template模块中的结构进行描述。

  • 第二部分为执行getBaseTransformPreset函数拿到@vue/compiler-core包中内置的nodeTransformsdirectiveTransforms转换函数。

  • 第三部分为将传入的options.nodeTransformsoptions.directiveTransforms分别和本地的nodeTransformsdirectiveTransforms进行合并得到一堆新的转换函数,和模版AST抽象语法树一起传入到transform函数中执行,就会得到转换后的javascript AST抽象语法树。在这一过程中v-forv-model等指令已经被转换函数给处理了。得到的javascript AST抽象语法树的结构和将要生成的render函数的结构是一模一样的,所以说javascript AST抽象语法树就是对render函数的结构进行描述。

  • 第四部分为由于已经拿到了和render函数的结构一模一样的javascript AST抽象语法树,只需要在generate函数中遍历javascript AST抽象语法树进行字符串拼接就可以得到render函数了。

关注