从源码看Vue编译器,运行时,打包之间的工作关联

3 阅读2分钟

先明确这几种概念

Vue编译器

常规意义上编译的运行产物是供底层硬件运行的二进制编码,而vue编译器运行产物是渲染函数

渲染函数运行的到的产物是虚拟Dom

在源码中,编译器相关逻辑由compile-corecompile-dom包定义

编译的工作主要是完成模板的解析,到生成Ast,再到创建渲染函数,也就是解析.vue文件中的Template中的vue所定义的指令和插值语法,生成JS描述的Vnode结构;

运行时

runtime-coreruntime-dom包定义,主要功能有:

  1. APP实例的创建
  2. 响应式接管
  3. Patch Vnode并最后生成真实Dom
  4. 一些Api的定义,如reftorRefs
  5. 。。。。。。

构建和打包

WebpackVite解析依赖、合并和拆分模块 todo:更详细一些

vue的几种工作方式

首先runtime模块非常依赖compile模块生成的渲染函数以及其生成的vnode数据结构执行功能

vue包大致分为两种:

  • 包含Compiler
  • 不包含Compiler

不包含Compiler的,在build的时候由打包工具执行编译工作,将.vue文件编译成渲染函数供runtime模块使用

包含Compiler的,则由runtime模块用到相应数据的时候实时编译

和常规意义上编译的不同

常规编译遵循先编译,后执行

vue的编译器并非如此,首先编译的结果不是由底层硬件认识的机器码而是vue工作需要的数据结构,其次对于包含编译器的执行环境,他是用到再编译的即时编译,有点类似浏览器JS编译的JIT

runtime模块在初次解析的时候,根组件rootComponent(也就是App.vue)不是render形成,而是手动构建(因为我们也看不到App.vue作为其他组件的子组件出现),type是component,其下所有的组件都是用到的时候再解析(mountComponent)

在mountComponent中:

  1. 不包含Compiler的运行时:拿到由打包工具编译好的渲染函数
  2. 包含Compiler的运行时:拿到模板代码调用Compiler进行编译得到渲染函数

但是大多数环境还是不包含Compiler的,因为过重了