Vue2.0 源码获取


项目地址

https://github.com/vuejs/vue

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

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

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

采用 rollup 构建源码。

Vue2.0 源码目录结构


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

  • src
    • compiler(编译相关)
    • core(Vue 核心库)
    • platforms(平台相关代码)
    • server(SSR 服务端渲染)
    • 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.js 和 vue.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. gitHooks:git 代码提交钩子
  2. pre-commit:代码提交时进行 eslint 校验
  3. commit-msg:代码提交信息校验
  4. 使用 flow 类型校验工具检测代码
  5. 使用 rollup 构建代码