什么是模板编译
把用户在标签中写的类似于原生HTML的内容进行编译,把原生HTML的内容找出来,再把非原生HTML找出来,经过一系列的逻辑处理生成渲染函数(render函数),这一段过程称之为模板编译过程。
模板编译内部流程:
第一步是将 模板字符串 转换成 element ASTs(解析器)
第二步是对 AST 进行静态节点标记,主要用来做虚拟DOM的渲染优化(优化器)
第三步是 使用 element ASTs 生成 render 函数代码字符串(代码生成器)
解析器
整体流程:
// 代码位置:/src/complier/parser/index.js
/**
* Convert HTML string to AST.
*/
export function parse(template, options) {
// ...
parseHTML(template, {
warn,
expectHTML: options.expectHTML,
isUnaryTag: options.isUnaryTag,
canBeLeftOpenTag: options.canBeLeftOpenTag,
shouldDecodeNewlines: options.shouldDecodeNewlines,
shouldDecodeNewlinesForHref: options.shouldDecodeNewlinesForHref,
shouldKeepComment: options.comments,
start (tag, attrs, unary) {
},
end () {
},
chars (text: string) {
},
comment (text: string) {
}
})
return root
}
从上面代码中可以看到,parse 函数就是解析器的主函数,在parse 函数内调用了parseHTML 函数对模板字符串进行解析,在parseHTML 函数解析模板字符串的过程中,如果遇到文本信息,就会调用文本解析器parseText函数进行文本解析;如果遇到文本中包含过滤器,就会调用过滤器解析器parseFilters函数进行解析。
优化器
标记静态节点
标记静态根节点
当前节点是静态节点,并且有子节点,并且子节点不是单个静态文本节点这种情况会将当前节点标记为根静态节点。
代码生成器
代码生成阶段主要的工作就是根据已有的AST生成对应的render函数供组件挂载时调用,组件只要调用的这个render函数就可以得到AST对应的虚拟DOM的VNode。
核心代码:
总结:
参考:
https://segmentfault.com/a/1190000013763590
https://vue-js.com/learn-vue/complie/HTMLParse.html#_5-%E5%9B%9E%E5%BD%92%E6%BA%90%E7%A0%81