Vue 的编译模块包含 4 个目录:
compiler-core
compiler-dom // 浏览器
compiler-sfc // 单文件组件
compiler-ssr // 服务端渲染
compiler-core
compiler-dom // 浏览器
compiler-sfc // 单文件组件
compiler-ssr // 服务端渲染其中 compiler-core 模块是 Vue 编译的核心模块,并且是平台无关的。而剩下的三个都是在 compiler-core 的基础上针对不同的平台作了适配处理。Vue 的编译分为三个阶段,分别是:parse、transform、codegen。其中 parse 阶段将模板字符串转化为语法抽象树 AST。transform 阶段则是对 AST 进行了一些转换处理。codegen 阶段根据 AST 生成对应的 render 函数字符串。ParseVue 在解析模板字符串时,可分为两种情况:以 < 开头的字符串和不以 < 开头的字符串。<<不以 < 开头的字符串有两种情况:它是文本节点或 {{ exp }} 插值表达式。<{{ exp }}而以 < 开头的字符串又分为以下几种情况:<

元素开始标签


元素结束标签


注释节点

文档声明
元素开始标签
元素结束标签
注释节点 文档声明 用伪代码表示,大概过程如下:
e (s.length) {
if (startsWith(s, '{{')) {

// 如果以 '{{' 开头

node = parseInterpolation(context, mode)
} else if (s[0] === '<') {

// 以 < 标签开头

if (s[1] === '!') {

if (startsWith(s, '
AST 节点AST 节点所有的 AST 节点定义都在 compiler-core/ast.ts 文件中,下面是一个元素节点的定义:
rt interface BaseElementNode extends Node {
type: NodeTypes.ELEMENT // 类型
ns: Namespace // 命名空间 默认为 HTML,即 0
tag: string // 标签名
tagType: ElementTypes // 元素类型
isSelfClosing: boolean // 是否是自闭合标签 例如


props: Array // props 属性,包含 HTML 属性和指令
children: TemplateChildNode[] // 字节点
}
rt interface BaseElementNode extends Node {
type: NodeTypes.ELEMENT // 类型
ns: Namespace // 命名空间 默认为 HTML,即 0
tag: string // 标签名
tagType: ElementTypes // 元素类型
isSelfClosing: boolean // 是否是自闭合标签 例如


props: Array // props 属性,包含 HTML 属性和指令
children: TemplateChildNode[] // 字节点
}一些简单的要点已经讲完了,下面我们再从一个比较复杂的例子来详细讲解一下 parse 的处理过程。


{{ test }}


一个文本节点
good job!




{{ test }}


一个文本节点
good job!

上面的模板字符串假设为 s,第一个字符 s[0] 是 < 开头,那说明它只能是刚才所说的四种情况之一。 这时需要再看一下 s[1] 的字符是什么:<

如果是 ! ,则调用字符串原生方法 startsWith() 看看是以 '

{{ test }}


一个文本节点
good job!