打算开始学习vue的源码开始,我开始 serach 关键词:vue 源码,可是发现很多都不是我想要看到的东西,所以打算记录下来,学习的记录和日后分享。我在想这个文章的名字时,手把手系列?十分钟系列?小白到大佬系列?都不是,只是单纯的学习笔记
文件结构
当我从 github 上 clone Vue 源码后,我看到很多熟悉的文件夹命名,以及配置文件,但对于我个小菜鸡,我还是想整体了解一下每个文件夹的内容,然后再去深挖~
有些我自己现在还不是很懂的后续再补上~
├─benchmarks
├─dist 打包后文件目录
├─examples 部分示例
├─flow 声明静态类型
├─packages vue可被分成的其他npm包
│ ├─vue-server-renderer
│ ├─vue-template-compiler
│ ├─weex-template-compiler
│ └─weex-vue-framework
├─scripts
├─src 主要源码
│ ├─compiler
│ ├─core 核心代码
│ ├─platforms 平台相关内容
│ ├─server 服务端渲染相关
│ ├─sfc
│ └─shared
├─test 测试用例
└─types 类型定义
└─test
从入口文件开始
首先,我们拿到一个文件后,我们应该养成习惯去查看项目根目录下的package.json文件。文件的基本构成:项目名称、版本、描述、执行命令、项目依赖等。
其中执行命令 script是我们当前所关注的,对于项目的文件结构,我们需要去找到项目的启动的入口文件,接下来我们去一步一步的找到vue
分析命令
"scripts": {
"dev": "rollup -w -c scripts/config.js --environment TARGET:web-full-dev"
}
rollup是一个 JavaScript 模块打包器。感兴趣的话可以去具体的研究,这里我们不做具体的探究。那我们知道这里它存在的作用就是对js进行打包处理。
我们来具体看一下这个命令的含义:
-
-w
watch 监听源文件是否有改动,有改动重新打包 -
-c
config 使用配置文件scripts/config.js
-
--environment
传递给配置文件的环境变量,这里传递的是目标文件 TARGET
根据以上,我们可以得知,该命令为使用 scripts/config.js
中的配置文件去打包 TARGET:web-full-dev
,我们想知道这个targt 具体指的是什么,我们需要去看一下config配置文件
层层递进
-
scripts\config.js
中我们可以找到,最下方为该文件的js执行部分,其中先去判断了我们所传入的Target,然后调用了genConfig
// 判断传入的环境变量
if (process.env.TARGET) {
module.exports = genConfig(process.env.TARGET)
}
- 我们继续往上看,
genconfig
根据函数名我们可以得知,为获取config这样的一个功能,Target为传入的name
,文件的上方定义了builds
,一个属性对应一个Target*,这样我们可以找到我们专注的web-full-dev
// builds 对象,属性名对应Target
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
}
// ...
}
// ...
// 这里传入的name 就是Target
function genConfig (name) {
const opts = builds[name]
// ... other config
}
从上可以看出,我们需要的是入口文件即entry中对应的web/entry-runtime-with-compiler.js
- 打开
entry-runtime-with-compiler.js
, 在文件上方,我们可以看到这个文件中import Vue
,我们所需要的是去追根到Vue的起始,所以就找到了上一层runtime/index
// 引入了Vue的实例
import Vue from './runtime/index'
- 打开上一步我们找到的
src/platforms/web/runtime/index.js
文件,第一行就引入了import Vue from 'core/index'
没关系我们继续,酒香不怕巷子深 src\core\index.js
// 又一次是引入了Vue的实例
import Vue from './instance/index'
6.src/core/instance\index.js
,惊喜~ ,在这里我们找到了Vue的构造函数,构造函数中仅调用了init
方法,_init
方法哪里来的呢,当然是文件下方在Vue原型上绑定的方法,接下来我们会以一个的去
// Vue的构造函数
function Vue (options) {
//... 验证环境
this._init(options)
}
// 在Vue原型上绑定实例方法
initMixin(Vue) // init
stateMixin(Vue) // $set $delete $watch
eventsMixin(Vue) // $on $once $off $emit
lifecycleMixin(Vue) // _update $forceUpdate $destroy
renderMixin(Vue) // $nextTick _render
总结
综上,小结一下追根顺序
package.json
--> scripts/config.js
--> web/entry-runtime-with-compiler.js
--> src/platforms/web/runtime/index.js
--> src/core/index.js
--> src/core/instance/index.js