先明确这几种概念
Vue编译器
常规意义上编译的运行产物是供底层硬件运行的二进制编码,而vue编译器运行产物是渲染函数
渲染函数运行的到的产物是虚拟Dom
在源码中,编译器相关逻辑由compile-core和compile-dom包定义
编译的工作主要是完成模板的解析,到生成Ast,再到创建渲染函数,也就是解析.vue文件中的Template中的vue所定义的指令和插值语法,生成JS描述的Vnode结构;
运行时
由runtime-core和runtime-dom包定义,主要功能有:
- APP实例的创建
- 响应式接管
- Patch Vnode并最后生成真实Dom
- 一些Api的定义,如
ref,torRefs等 - 。。。。。。
构建和打包
Webpack,Vite解析依赖、合并和拆分模块
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中:
- 不包含Compiler的运行时:拿到由打包工具编译好的渲染函数
- 包含Compiler的运行时:拿到模板代码调用Compiler进行编译得到渲染函数
但是大多数环境还是不包含Compiler的,因为过重了