Vue2.0 源码获取


项目地址

https://github.com/vuejs/vue

clone 一份源码项目到自己的 github 仓库,方便在阅读的过程中编写注释。

目前比较稳定的版本是 2.6.14 所以我们选择分析这个版本的源码,因为到目前为止 3.0 虽然已经发布但是还不够成熟,还有很长的一段过度期。

采用 flow 代替 typescript 编写的源码。

采用 rollup 构建源码。

Vue2.0 源码目录结构


src 是核心目录,以外的都是一些配置文件。

  • src
    • compiler(编译相关)
    • coreVue 核心库)
    • platforms(平台相关代码)
    • serverSSR 服务端渲染)
    • sfc.vue 文件编译为 javascript 对象)
    • shared(公共代码)
目录名称 描述
compiler compiler 目录包含 Vue.js 所有编译相关的代码。它包括把模板解析成 ast 语法树,ast 语法树优化,代码生成等功能。
编译的工作可以在构建时做(借助 webpack、vue-loader 等辅助插件);也可以在运行时做,使用包含构建功能的 Vue.js。显然,编译是一项耗性能的工作,所以更推荐前者——离线编译。
core core 目录包含了 Vue.js 的核心代码,包括内置组件、全局 API 封装,Vue 实例化、观察者、虚拟 DOM、工具函数等等。
这里的代码可谓是 Vue.js 的灵魂,也是我们之后需要重点分析的地方。
platform Vue.js 是一个跨平台的 MVVM 框架,它可以跑在 web 上,也可以配合 weex 跑在 native 客户端上。platform 是 Vue.js 的入口,2 个目录代表 2 个主要入口,分别打包成运行在 web 上和 weex 上的 Vue.js。
我们会重点分析 web 入口打包后的 Vue.js,对于 weex 入口打包的 Vue.js,感兴趣的同学可以自行研究。
server Vue.js 2.0 支持了服务端渲染,所有服务端渲染相关的逻辑都在这个目录下。注意:这部分代码是跑在服务端的 Node.js,不要和跑在浏览器端的 Vue.js 混为一谈。
服务端渲染主要的工作是把组件渲染为服务器端的 HTML 字符串,将它们直接发送到浏览器,最后将静态标记”混合”为客户端上完全交互的应用程序。
sfc 通常我们开发 Vue.js 都会借助 webpack 构建, 然后通过 .vue 单文件来编写组件。
这个目录下的代码逻辑会把 .vue 文件内容解析成一个 JavaScript 的对象。
shared Vue.js 会定义一些工具方法,这里定义的工具方法都是会被浏览器端的 Vue.js 和服务端的 Vue.js 所共享的。
总结 从 Vue.js 的目录设计可以看到,作者把功能模块拆分的非常清楚,相关的逻辑放在一个独立的目录下维护,并且把复用的代码也抽成一个独立目录。
这样的目录设计让代码的阅读性和可维护性都变强,是非常值得学习和推敲的。

Vue2.0 不同构建版本区别


clone 源码项目后,啥都不用干先 yarn 安装依赖包,然后直接 npm run build 打包项目。看看 vue 的版本有哪些,虽然版本有很多,但是都是有规律的。如下图:

image.png

UMD CommonJS ES Module
Full vue.js vue.common.js vue.esm.js
Runtime-only vue.runtime.js vue.runtime.common.js vue.runtime.esm.js
Full(production) vue.min.js
Runtime-only(production) vue.runtime.min.js

new Vue 中 传入 template 或者 render 的区别,编译器会将 template 转换成 render

vue-cli 默认使用 ES Module 中的 vue.runtime.esm.js

单文件组件(xxx.vue)浏览器是不支持的,所以在打包的时候需要将我们的单文件组件转换为 javascript 对象,在转换 javascript 对象的过程中还会将我们的 template 转换为 render 函数,所以单文件组件在运行时也不需要编译器。

术语

  • 完整版:同时包含编译器和运行时的版本
  • 编译器:用来将模板字符串编译成 JavaScript 渲染函数的代码,体积大、效率低
  • 运行时(推荐使用):用来创建 Vue 实例、渲染并处理虚拟 DOM 等代码,体积小、效率高。基本上就是去除编译器的3000多行代码。
  • UMD:代表通用版本,同时兼容 CommonJS ES Module 等多种模块化方式。
  • ESM:从 2.6 版本开始,vue 提供了两个构建文件分别是 vue.esm.jsvue.runtime.esm.js,为现代打包工具提供的版本。ESM 格式被设计为可以被静态分析,所以打包工具可以利用这一点来进行 tree-shaking 将用不到的代码排除,从而减少打包体积。

Vue2.0 源码调试


前置

  1. github 中拉取 vue2.0 源码
  2. 首先要知道 vue 源代码使用的是 rollup 打包工具并非 webpack
  3. package.json 中为 rollu_p 开启 —_sourcemap
  4. npm run dev 运行 vue, 在 dist 目录中会多出一个 vue.js.map 文件
  5. 新建 index.html 入 dist/vue.js
  6. vue.js 是完整版(包含编译器和运行时)
  7. vue2.0 源码使用了 flow 类型校验工具,代码会提示类型错误,可以通过 vscode 配置 typescript.validate.enable: false javascript.validate.enable: false关闭校验

渐进式提问
持续抛出更多的小问题,从而慢慢了解 vue,这是一个循序渐进的过程。

  1. Vue 是如何构建的?
  2. 其次就是 new Vue 中的 el、template、render 同时设置会渲染哪个?
  3. Vue 首次渲染过程是怎样的?
  4. 数据响应式处理过程是怎样的?
  5. data 中的对象、数组重新赋值,视图是否会更新?
  6. 在什么地方重写了数组的方法?

Vue2.0 源码收获


不仅是学习源码

  1. gitHooksgit 代码提交钩子
  2. pre-commit:代码提交时进行 eslint 校验
  3. commit-msg:代码提交信息校验
  4. 使用 flow 类型校验工具检测代码
  5. 使用 rollup 构建代码