调试模板编译过程

Vue

# 模板html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>compile</title>
</head>
<body>
  <div id="app">
    <!-- 静态根节点 -->
    <h1>Vue<span>模板编译过程</span></h1>
    <!-- 有插值表达式,不是静态根节点 -->
    <div>{{ msg }}<p>hello</p></div>
    <!-- 没有字标签,不是静态根节点 -->
    <div>是否显示</div>
  </div>
  <script src="../../dist/vue.js"></script>
  <script>
    const vm = new Vue({
      el: '#app',
      data: {
        msg: 'Hello compiler',
        isShow: false
      },
      methods: {
        handler () {
          console.log('test')
        }
      }
    })
  </script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 设置断点

  1. 入口文件entry-runtime-with-compile.js中的compileToFunctions函数上设置断点

image

按F5刷新

# 开始调试

  1. 按F11进入compileToFunctions函数,按F10到check cache的部分

image

这个位置是使用字符串模板作为key来缓存中查找是否有编译好的渲染函数,如果有就直接返回,否则继续往下执行,这里首次渲染,还没有缓存的函数,所以继续向下执行.

  1. 执行到compile函数,开始编译模板

image

  1. 按F11进入compile函数,在这个函数中,首先合并options选项

image

  1. 继续往下找到baseCompile的执行函数,设置断点,并按F8执行到这个断点

image

  1. 按F11进入这个函数,这是模板编译的核心位置,三件事情,把模板字符串转换成ast对象,优化ast对象,把优化后的ast对象转换成字符串形式的代码.下面是第一件事情,将模板字符串转换成ast对象,可以看到ast对象里面有type,tag,属性,parent和children等,不过目前还没有static属性

image

  1. 执行完optimize之后可以看到,ast对象中添加了有关静态节点的属性
  • 最大的div不是静态节点也不是静态根节点

image

  • h1对象是静态根节点,里面有子元素还都是文本节点

image

  • 第二个子div有插值表达式不是静态节点,也不是静态根节点

image

  • 最后一个子div是静态节点,不是静态根节点,因为没有子元素只有文本节点

image

  1. 按F10执行完generate函数,可以看到code中有了生成的最终的代码

image

然后看参数ast,可以看到里面添加了一个属性是staticProcessed,已经处理完毕

image

  1. baseCompile函数已经执行完毕,回到compile函数中,记录编译的错误和信息,返回编译好的对象,compile执行完毕之后,会到入口函数compileToFunctions中,此时在createFunction中设置断点,F8执行到这里

image

  1. 按F11进入这个函数,这个函数通过 newFunction 转换成了匿名函数

image

  1. 执行完毕之后可以看到选项被转换成了匿名函数,同样staticRenderFns数组也调用这个函数转换成匿名函数,如图

image

  1. 最终把生成的结果缓存返回

image

  1. 返回之后将render和staticRenderFns存储到options的属性上,到此整个编译的过程就执行完毕

image

更新时间: 2022-01-13 21:13