Vue编译器AST抽象语法树源码分析

Vue编译器AST抽象语法树源码分析

目录

引言

baseCompile主要核心代码

如何写一个程序来识别 Token

parse 函数解析模板字符串

引言

接上篇  Vue编译器源码分析compile 解析

baseCompile主要核心代码 // `createCompilerCreator` allows creating compilers that use alternative // parser/optimizer/codegen, e.g the SSR optimizing compiler. // Here we just export a default compiler using the default parts. var createCompiler = createCompilerCreator(function baseCompile( template, options ) { var ast = parse(template.trim(), options); if (options.optimize !== false) { } var code = generate(ast, options); return { ast: ast, render: code.render, staticRenderFns: code.staticRenderFns } });

可以看到 baseCompile 的代码非常的简短主要核心代码。

var ast =parse(template.trim(), options); parse 会用正则等方式解析 template 模板中的指令、class、style等数据,形成AST。

optimize(ast, options); optimize 的主要作用是标记 static 静态节点,这是 Vue 在编译过程中的一处优化,后面当 update 更新界面时,会有一个 patch 的过程, diff 算法会直接跳过静态节点,从而减少了比较的过程,优化了 patch 的性能。

var code =generate(ast, options); 生成目标平台所需的代码,将 AST 转化成 render function 字符串的过程,得到结果是 render 的字符串以及 staticRenderFns 字符串。

最终 baseCompile 的返回值

{ ast: ast, render: code.render, staticRenderFns: code.staticRenderFns }

最终返回了抽象语法树( ast ),渲染函数( render ),静态渲染函数( staticRenderFns ),且render 的值为code.render ,staticRenderFns 的值为code.staticRenderFns ,也就是说通过 generate 处理 ast 之后得到的返回值 code 是一个对象 ...

接下来让我们把目光聚焦在 Vue 的 parser,它是如何将字符串模板解析为抽象语法树(AST)的。

var ast = parse(template.trim(), options);

在讲解parse之前你需要对编译过程以及其中的技术点有个宏观、概要的了解。

引用自维基百科:

它主要的目的是将便于人编写、阅读、维护的高级计算机语言所写作的源代码程序,翻译为计算机能解读、运行的低阶机器语言的程序。源代码一般为高阶语言(High-level language),如Pascal、C、C++、C# 、Java等,而目标语言则是汇编语言或目标机器的目标代码(Object code)。

编译器的技术分为词法分析、语法分析和语义分析三个部分,通常编译器的第一项工作叫做词法分析。就像阅读文章一样,文章是由一个个的中文单词组成的。程序处理也一样,只不过这里不叫单词,而是叫做“词法记号”,英文叫 Token。

<div id="app" v-if="ret">{{ message }}</div>

编译器会识别出 div a span 这些标签,id class style v-if v-for 这样的属性、指令,还有花括号符号这样的插值操作...等。这些都是 Token。

如何写一个程序来识别 Token

那么,如何写一个程序来识别 Token 呢?

其实,我们可以手写程序制定一些规则来区分每个不同的 Token,这些规则用“正则文法”表达,符合正则文法的表达式称为“正则表达式”。通过他们来完成具体的词法分析工作。

编译器下一个阶段的工作是语法分析。词法分析是识别一个个的单词,而语法分析就是在词法分析的基础上识别出程序的语法结构。这个结构是一个树状结构,是计算机容易理解和执行的。

程序也要定义良好的语法结构,它的语法分析过程,就是构造这么一棵树。一个程序就是一棵树,这棵树叫做抽象语法树(Abstract Syntax Tree,AST)。树的每个节点(子树)是一个语法单元,这个单元的构成规则就叫“语法”。

而我们这里要讲的 parser 就是在编译器对源代码处理的第一步,parser 把某种特定格式的文本(字符串)转换成某种数据结构的程序(对象),并且这个数据结构是编译器能够理解的,因为编译器的后续步骤,比如上面提到的 句法分析,类型检查/推导,代码优化,代码生成 等等都依赖于该数据结构。

注:parse & parser 这两个单词,不要混淆,parse 是动词,代表“解析”的过程,parser 是名词,代表“解析器”。

Vue 的编译器也不例外, 在词法分析阶段 Vue 会把字符串模板解析成一个个的令牌(token),该令牌将用于句法分析阶段,在句法分析阶段会根据令牌生成一棵 AST,最后再根据该 AST生成最终的渲染函数,这样就完成了代码的生成。

var ast = parse(template.trim(), options); parse 函数解析模板字符串

回归到刚刚的代码,已知 parse 函数就是用来解析模板字符串的,最终生成AST。

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 函数内部主要通过调用parseHTML 函数对模板字符串进行解析,实际上parseHTML 函数的作用就是用来做词法分析的,而parse函数的作用则是在词法分析的基础上做句法分析从而生成一棵AST。本节我们主要分析一下Vue是如何对模板字符串进行词法分析的,也就是parseHTML 函数的实现。

接下来我们章节会分为两个方向

一:parseHTML 函数源码解析

二:Vue编译器token解析规则-正则分析

以上就是Vue编译器AST抽象语法树源码分析的详细内容,更多关于Vue编译器AST抽象语法树的资料请关注易知道(ezd.cc)其它相关文章!

推荐阅读

    vue项目一些常见问题

    vue项目一些常见问题,组件,样式,**样式污染问题**同样的样式不需要在每个组件都复制组件内单独的样式加外层class包裹。加scope。否则只是

    01-Vue项目实战-网易云音乐-准备工作

    01-Vue项目实战-网易云音乐-准备工作,网易,项目,前言在接下来的一段时间,我会仿照网易云音乐,利用Vue开发一个移动端的网易云音乐项目。在做

    01- 第一天 spring boot2.3.1 +vue3.0 后台管理系统的研发

    01- 第一天 spring boot2.3.1 +vue3.0 后台管理系统的研发,自己的,后台,后台框架一直想开发一套完全属于自己的后台,但是18年的时候,曾经答

    电脑配置单源码|中配电脑配置单

    电脑配置单源码|中配电脑配置单,,1. 中配电脑配置单mastercam对于电脑配制要求不会很高,画图编程软件主要是显卡这方面要求比较高点,台式机

    Vue项目中 App.vue文件

    Vue项目中 App.vue文件,文件,内容, 在App.vue文件中,定义了一个id为app的div,在这个div板块中放置Helloworld组件,文件内容如下图所示:在

    去哪里下载免费又好看的网站源码

    去哪里下载免费又好看的网站源码,源码,网站,本文目录去哪里下载免费又好看的网站源码我有几个网站源代码 想卖,哪个网站是专门在上面卖的最

    1-Vue构造函数的生成

    1-Vue构造函数的生成,函数,属性,版本:@2.6.10环境:web ;思维图:www.processon.com/view/link/5…我们使用的Vue是一个经过层层加强的构造函数

    vue的跨域是什么意思

    vue的跨域是什么意思,跨域,浏览器,代理,请求,服务器,同源策略,在vue中,跨域是指浏览器不能执行其他网站的脚本;它是浏览器同源策略造成的,是浏览器