Vue(v2.6.14)源码解毒(一)(准备工作)
前言
Vue3 出来也有好一整子了,但 Vue2 的源码原理学习,不论在升职加薪还是在另谋高就的路上,一直是一个必要的环节,正应了“面试造火箭,上班拧螺丝”这句话。尽管之前对 Vue2 的源码也有学习过,但是一直没有进行一个系统的总结,说白了就是懒。最近在掘金上看到 李永宁 大佬的 《Vue 源码解读》 系列文章后,又开始蠢蠢欲动了。这次主要是对核心实现的一个梳理,细节方面不会太过介绍。
源码地址
本次学习的 Vue源码 为 2.6.14
版本,git命令下载:
git clone https://github.com/vuejs/vue.git
这是我标记好注释的源码:
git clone https://github.com/zhangquanming/vue.git
Flow Flow 是 facebook 出品的 JavaScript 静态类型检查工具。Vue 2.x 的源码就是利用了 Flow 做静态类型检查。类似 Flow 的工具还有如 TypeScript。大家对TS应该比较了解,对 Flow 感兴趣可以去 官方文档 自行了解。
调试环境 源码下载后,进入根目录,安装依赖
npm i
修改dev脚本,添加 sourcemap
//package.json
{
"scripts": {
"dev": "rollup -w -c scripts/config.js --sourcemap --environment TARGET:web-full-dev",
// ...
}
}
启动项目:
npm run dev
运行成功,可以在
dist
目录下找到打包出来的vue.js
和 vue.js.map
文件。接下来我们在 /examples
目录下新建文件 test.html
Vue - 锐客网 {{ msg }}
在浏览器打开
test.html
文件,使用控制台,就可以进行断点调试,一步步看其运行过程了。目录结构
|-- benchmarks# 性能、基准测试
|-- dist# 发布目录
|-- examples# 范例
|-- flow# flow 类型检查
|-- packages# 核心代码之外的独立库
|-- scripts# 构建配置、脚本
|-- src# 源码目录
|-- test# 测试目录
|-- types# TS 类型声明
Vue 的源码都在 src 下,下面我们重点看下 src 目录:
src
|-- compiler# 编译相关,模板解析成 ast 语法树,ast 语法树优化,代码生成等功能。
|-- core# 核心代码
||-- components# 通用组件,如 keep-alive
||-- config.js# 一些默认配置项
||-- global-api# 全局API封装
||-- index.js
||-- instance# 构造函数等
||-- observer# 响应式相关
||-- util# 工具函数
|`-- vdom# 虚拟DOM相关
|-- platforms# 不同平台的支持
||-- web# web端
|`-- weex# native 客户端
|-- server# 服务端渲染,这部分代码是跑在服务端的 Node.js。
|-- sfc# .vue 文件解析,将 .vue 文件内容解析成一个 JS 对象。
`-- shared# 共享代码,定义了一些工具方法,被浏览器端的 Vue.js 和服务端的 Vue.js 所共享的。
查找入口 通过之前运行构建命令
npm run dev
,找到构建脚本我就能发现://package.json
{
"scripts": {
"dev": "rollup -w -c scripts/config.js --sourcemap --environment TARGET:web-full-dev",
// ...
}
}
- dev 脚本中
-c scripts/config.js
是配置文件所在。 - 参数
TARGET:web-full-dev
是输出文件配置项。
// scripts/config.js
const builds = {
// ...
// Runtime+compiler development build (Browser)
'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
}
// ...
format
表示构建出来的文件规范:cjs
表示 Common.js 规,用于 webpack1。es
表示 ES Module 规范,ES模块,用于 webpack2+。umd
表示 UMD 规范,兼容 cjs 和 amd ,用于浏览器。
- Runtime Only (仅运行时)——通常需要借助如 webpack 的 vue-loader 工具把 .vue 文件编译成 JS 渲染函数,因为构建后已经编译完成,所以使用时只需运行时的包即可,包的体积更小。
- Runtime + Compiler (运行时+编译器)——如果没有进行预编译,或者使用了动态编译模板,如 Vue 的 template 属性并传入一个字符串, 需要在客户端进行编译,则需要含有编译器的全量包。
resolve('web/entry-runtime-with-compiler.js')
,先看一下 resolve
函数:// scripts/config.js
const aliases = require('./alias')
const resolve = p => {
const base = p.split('/')[0]
if (aliases[base]) {
return path.resolve(aliases[base], p.slice(base.length + 1))
} else {
return path.resolve(__dirname, '../', p)
}
}
// scripts/alias.js
const path = require('path')
const resolve = p => path.resolve(__dirname, '../', p)
module.exports = {
vue: resolve('src/platforms/web/entry-runtime-with-compiler'),
compiler: resolve('src/compiler'),
core: resolve('src/core'),
shared: resolve('src/shared'),
web: resolve('src/platforms/web'),
weex: resolve('src/platforms/weex'),
server: resolve('src/server'),
sfc: resolve('src/sfc')
}
最终我们得出入口文件为:
src/platforms/web/entry-runtime-with-compiler.js
, 接下来我们就从这个入口文件出发,看一看整个 vue 的实现。相关链接 Vue(v2.6.14)源码解毒(预):手写一个简易版Vue
【Vue(v2.6.14)源码解毒(一)(准备工作)】Vue(v2.6.14)源码解毒(一):准备工作
[Vue(v2.6.14)源码解毒(二):初始化和挂载(待续)]()
[Vue(v2.6.14)源码解毒(三):响应式原理(待续)]()
[Vue(v2.6.14)源码解毒(四):更新策略(待续)]()
[Vue(v2.6.14)源码解毒(五):render和VNode(待续)]()
[Vue(v2.6.14)源码解毒(六):update和patch(待续)]()
[Vue(v2.6.14)源码解毒(七):模板编译(待续)]()
如果觉得还凑合的话,给个赞吧!!!也可以来我的个人博客逛逛 https://www.mingme.net/
推荐阅读
- vue-cli|vue-cli 3.x vue.config.js 配置
- 2020-04-07vue中Axios的封装和API接口的管理
- Android事件传递源码分析
- VueX--VUE核心插件
- Quartz|Quartz 源码解析(四) —— QuartzScheduler和Listener事件监听
- [源码解析]|[源码解析] NVIDIA HugeCTR,GPU版本参数服务器---(3)
- ffmpeg源码分析01(结构体)
- Java程序员阅读源码的小技巧,原来大牛都是这样读的,赶紧看看!
- vue组件中为何data必须是一个函数()
- 用npm发布一个包的教程并编写一个vue的插件发布