资讯专栏INFORMATION COLUMN

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

3403771864 / 622人阅读

 直接进入核心现在说说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 静态节点,可以当 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 函数对模板字符串进行解析,简单来说就是用来做词法分析的。不同的是而arse函数的作用则是在词法分析的基础上做句法分析从而生成一棵AST。

  以上就是Vue编译器AST抽象语法树源码分析的详细内容,请大家关注更多后续精彩内容。


文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/127807.html

相关文章

  • vue分析之template模板解析AST

    摘要:注意看注释很粗很简单,我就是一程序员姓名,年龄,请联系我吧是否保留注释定义分隔符,默认为对于转成,则需要先获取,对于这部分内容,做一个简单的分析,具体的请自行查看源码。其中的负责修改以及截取剩余模板字符串。 通过查看vue源码,可以知道Vue源码中使用了虚拟DOM(Virtual Dom),虚拟DOM构建经历 template编译成AST语法树 -> 再转换为render函数 最终返回...

    2bdenny 评论0 收藏0
  • Vue源码解析之Template转化为AST

    摘要:下面用具体代码进行分析。匹配不到那么就是开始标签,调用函数解析。如这里的转化为加上是为了的下一步转为函数,本文中暂时不会用到。再把转化后的内容进。 什么是AST 在Vue的mount过程中,template会被编译成AST语法树,AST是指抽象语法树(abstract syntax tree或者缩写为AST),或者语法树(syntax tree),是源代码的抽象语法结构的树状表现形式。...

    huangjinnan 评论0 收藏0
  • JS每日一题:简述一下Vue.js的template编译过程?

    摘要:问简述一下的编译过程先上一张图大致看一下整个流程从上图中我们可以看到是从后开始进行中整体逻辑分为三个部分解析器将模板字符串转换成优化器对进行静态节点标记,主要用来做虚拟的渲染优化代码生成器使用生成函数代码字符串开始前先解释一下抽象 20190215问 简述一下Vue.js的template编译过程? 先上一张图大致看一下整个流程showImg(https://image-static....

    NicolasHe 评论0 收藏0
  • 聊聊Vue.js的template编译

    摘要:具体可以查看抽象语法树。而则是带缓存的编译器,同时以及函数会被转换成对象。会用正则等方式解析模板中的指令等数据,形成语法树。是将语法树转化成字符串的过程,得到结果是的字符串以及字符串。里面的节点与父节点的结构类似,层层往下形成一棵语法树。 写在前面 因为对Vue.js很感兴趣,而且平时工作的技术栈也是Vue.js,这几个月花了些时间研究学习了一下Vue.js源码,并做了总结与输出。 文...

    gnehc 评论0 收藏0
  • Vue源码解析:模版字符串转AST语法

    摘要:通过对源码阅读,想写一写自己的理解,能力有限故从尤大佬第一次提交开始读,准备陆续写模版字符串转语法树语法树转函数双向绑定原理虚拟比较原理其中包含自己的理解和源码的分析,尽量通俗易懂由于是的最早提交,所以和最新版本有很多差异,后续将陆续补充, 通过对 Vue2.0 源码阅读,想写一写自己的理解,能力有限故从尤大佬2016.4.11第一次提交开始读,准备陆续写: 模版字符串转AST语法...

    chengjianhua 评论0 收藏0

发表评论

0条评论

3403771864

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<