前面两部分介绍了Vuejs的各个发布版本,以及它们的区别。也了解了VueJS源码的代码结构,以及基本的构建过程。
下一代ES6 模块打包工具 rollup 是通过 entry 文件中的模块引入来分析依赖关系并完成代码打包的,所以下面我们的重点就是这个 entry 文件了。
以 src/entries/web-runtime-with-compiler.js 为例。
打开文件,第一行有个
/* @flow */
这又是什么,没见过,Google之。https://flowtype.org/
原来这货时一个javascript静态类型检查器,代码中有个 .flowconfig 文件就是给它用的。好的,这不是我们的重点,略之。
继续向下看代码
下面就是一连串的import语句了,我们先来看看简单的
import { warn, cached } from 'core/util/index'
其实在 'core/util/index' 文件中并没有 warn 和 cached 的直接定义,也是从其他模块中引入的。具体来看一下,warn 是在 'core/util/debug' 模块中定义,而 cached 其实是在 'shared/util' 模块中定义的。
细心的话就会发现,在 'core/util/index' 文件中引入 'shared/util' 的时候,相对路径是不正确的,rollup是如何找到它的?这里有必要介绍一下 alias。
我们回顾一下build的过程,有个 getConfig 函数中用到了 alias, 并且在build目录下面有个 alias.js 文件,其实里面已经记录了这些别名的映射关系,所以我们在import的时候就可以直接使用别名来导入模块了。
import { query } from 'web/util/index'
是从 'platforms/web/util/index' 中引入了 query 这个依赖。
import { shouldDecodeNewlines } from 'web/util/compat'
是从 'platforms/util/compat' 中引入shouldDecodeNewlines 这个依赖。
import { compileToFunctions } from 'web/compiler/index'
则是从 'platforms/compiler/index' 中引入 compileToFunctions 这个依赖的。
import Vue from './web-runtime'
看名字就知道这个才是重点。
过一遍代码就会发现,这个文件的逻辑也相对简单。
从 './web-runtime' 中引入了Vue构造器, 并对Vue.prototype.$mount进行了包装。
- 首先是判断给定的el参数是否是
<html>
或<body>
。如果是的话,就给出警告并返回当前vue的实例对象,不做其它处理。- 然后判断当前vue实例对象是否配置了 render 属性。 如果没有就去查找或计算 template 属性,然后使用 compiler 模块构建 render 和 staticRenderFns 方法, 并将其注入到当前vue实例对象中。
- 最后调用原始的Vue.prototype.$mount方法。
另外,从 'build/config.js' 文件中可以知道 'web-runtime' 是构建 'vue.runtime.js' 的入口文件。而当前的构建入口文件,只是重用了 runtime 版本,并包装了compiler。
打开 'vue.runtime.js' 文件,发现这也是对原始Vue构造器的包装。这样逐级向上查找,我们就会找到最最原始的Vue构造器是如何定义和扩展的。
为何要如此关注Vue构造器的定义呢?因为个人理解在VueJS的开发中,最主要的就是如何去实例化Vue对象。
以后就可以具体到代码中一探究竟了。