Vue2.0 源码获取
项目地址
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 的版本有哪些,虽然版本有很多,但是都是有规律的。如下图:
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 源码调试
前置
- 在 github 中拉取 vue2.0 源码
- 首先要知道 vue 源代码使用的是 rollup 打包工具并非 webpack
- 在 package.json 中为 rollu_p 开启 —_sourcemap
- npm run dev 运行 vue, 在 dist 目录中会多出一个 vue.js.map 文件
- 新建 index.html 引入 dist/vue.js
- vue.js 是完整版(包含编译器和运行时)
- vue2.0 源码使用了 flow 类型校验工具,代码会提示类型错误,可以通过 vscode 配置 typescript.validate.enable: false 和 javascript.validate.enable: false关闭校验
渐进式提问
持续抛出更多的小问题,从而慢慢了解 vue,这是一个循序渐进的过程。
- Vue 是如何构建的?
- 其次就是 new Vue 中的 el、template、render 同时设置会渲染哪个?
- Vue 首次渲染过程是怎样的?
- 数据响应式处理过程是怎样的?
- 向 data 中的对象、数组重新赋值,视图是否会更新?
- 在什么地方重写了数组的方法?
Vue2.0 源码收获
不仅是学习源码
- gitHooks:git 代码提交钩子
- pre-commit:代码提交时进行 eslint 校验
- commit-msg:代码提交信息校验
- 使用 flow 类型校验工具检测代码
- 使用 rollup 构建代码