Vue 源码解析-0.前置准备
# 前言
本篇作为 Vue 源码解析的开篇,不会讲源码中的内容,谈谈我们如何查看和调试源码
# 下载仓库
我们选择当前较为稳定的 v2.6.10 (opens new window) 分支
git clone --branch v2.6.10 https://github.com/vuejs/vue.git
# 安装依赖
yarn
# 认识 Flow
由于代码中用了 Flow , 为了后续更方便的学习和调试代码,先了解下 Flow
Flow 与 TypeScript 类似,是一种 js 静态类型检测工具
至于两者的区别,我感觉 Flow 的侵入性较小, TypeScript 功能较强大
在 js 文件开头添加
/* @flow */
就表明需要采用 Flow 检测这个文件
# 一个简单的例子
// @flow
var str: number = 'hello world!';
console.log(str);
2
3
4
配置 Flow 后, 编辑器会提示说 'hello world!' string. This type is incompatible with number
# VS Code 配置
VS Code 自带检测工具,会与 Flow 冲突,导致打开 Vue 项目的时候各种报错。
因此需要进行工作区设置
.vscode/setting.json
{
"javascript.validate.enable": false,
}
2
3
或者禁用内置 TS 拓展
查找内置拓展:搜索的时候加个
@builtin
前缀,即@builtin TypeScript
至于 Flow 的其他配置,不是我们的重点,我们只需要阅读源码就够了
# 项目结构
参照 .github/CONTRIBUTING.md
的 Project Structure 部分,翻译并增加部分说明后如下所示:
├── scripts ------------------------------- 包含与构建相关的脚本和配置文件,主要看以下两个
│ ├── alias.js -------------------------- 源码和测试中使用到的模块导入别名
│ ├── config.js ------------------------- 生成 dist 目录下各种文件的构建配置
├── dist ---------------------------------- 构建后文件的输出目录
├── examples ------------------------------ 存放一些使用Vue开发的应用案例
├── flow ---------------------------------- 全局加载的 Flow 类型声明
├── packages ------------------------------ 单独分发的其他 NPM 包
├── test ---------------------------------- 测试文件
├── src ----------------------------------- 源码目录,基于 ES6 和 Flow 类型注释
│ ├── compiler -------------------------- 编译器代码,用来将 template 编译为 render 函数
│ │ ├── parser ------------------------ 存放将模板字符串转换成元素抽象语法树的代码
│ │ ├── codegen ----------------------- 存放从抽象语法树(AST)生成render函数的代码
│ │ ├── optimizer.js ------------------ 分析静态树,优化vdom渲染
│ ├── core ------------------------------ 包含平台无关的,通用的运行时代码
│ │ ├── observer ---------------------- 响应式实现,包含数据观测的核心代码
│ │ ├── vdom -------------------------- 虚拟 DOM 的 creation 和 patching 相关代码
│ │ ├── instance ---------------------- Vue 构造函数与原型方法
│ │ ├── global-api -------------------- 将 Vue 构造函数挂载上静态方法和属性,如 Vue.set = xxx
│ │ ├── components -------------------- 包含抽象出来的通用组件,目前只有 keep-alive
│ ├── server ---------------------------- 服务端渲染(server-side rendering)的相关代码
│ ├── platforms ------------------------- 不同平台特有的代码
│ │ ├── weex -------------------------- weex平台支持
│ │ ├── web --------------------------- web平台支持
│ │ │ ├── entry-runtime.js ---------------- 运行时构建的入口
│ │ │ ├── entry-runtime-with-compiler.js -- 独立构建版本的入口
│ │ │ ├── entry-compiler.js --------------- vue-template-compiler 包的入口文件
│ │ │ ├── entry-server-renderer.js -------- vue-server-renderer 包的入口文件
│ ├── sfc ------------------------------- 包含单文件组件(.vue文件)的解析逻辑,用于vue-template-compiler包
│ ├── shared ---------------------------- 整个代码库通用的代码,包含 constants 和 util
├── types --------------------------------- 包含TypeScript类型定义 .d.ts ,用于支持 ts 开发
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
# 入手
拿到一个项目,我们第一反应是看 package.json
,执行 npm run dev
的时候做了什么?可以看到
rollup -w -c --environment TARGET:web-full-dev
根据 scripts/config.js
指定的配置进行 rollup (opens new window) 进行打包
'web-full-dev': {
entry: resolve('web/entry-runtime-with-compiler.js'),
dest: resolve('dist/vue.js'),
format: 'umd',
env: 'development',
alias: { he: './entity-decoder' },
banner
},
2
3
4
5
6
7
8
入口为:src/platforms/web/entry-runtime-with-compiler.js
生成文件: dist/vue.js
# 断点调试
我们在 scripts/config.js
中的 genConfig 方法中的 config 对象的 output 属性中加上
sourcemap: true
然后执行 npm run dev
进行打包
选择 examples 中的任意项目,修改 js 的引用为 <script src="../../dist/vue.js"></script>
之后在浏览器中打开 html 文件,由于开了 sourcemap ,我们即可使用浏览器的开发者工具进行断点调试
# 规划
下一篇文章,我们来谈谈, Vue 实例化的时候都发生了什么