Vue源碼學習(一)——追根究底Vue

打算開始學習vue的源碼開始,我開始 serach 關鍵詞:vue 源碼,但是發現不少都不是我想要看到的東西,因此打算記錄下來,學習的記錄和往後分享。我在想這個文章的名字時,手把手系列?十分鐘系列?小白到大佬系列?都不是,只是單純的學習筆記

文件結構

當我從 githubclone Vue 源碼後,我看到不少熟悉的文件夾命名,以及配置文件,但對於我個小菜雞,我仍是想總體瞭解一下每一個文件夾的內容,而後再去深挖~
有些我本身如今還不是很懂的後續再補上~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是咱們當前所關注的,對於項目的文件結構,咱們須要去找到項目的啓動的入口文件,接下來咱們去一步一步的找到vuegit

分析命令

"scripts": {
  "dev": "rollup -w -c scripts/config.js --environment TARGET:web-full-dev"
}

rollup是一個 JavaScript 模塊打包器。感興趣的話能夠去具體的研究,這裏咱們不作具體的探究。那咱們知道這裏它存在的做用就是對js進行打包處理。 github

咱們來具體看一下這個命令的含義:web

  • -w watch 監聽源文件是否有改動,有改動從新打包
  • -c config 使用配置文件 scripts/config.js
  • --environment 傳遞給配置文件的環境變量,這裏傳遞的是目標文件 TARGET

根據以上,咱們能夠得知,該命令爲使用 scripts/config.js中的配置文件去打包 TARGET:web-full-dev,咱們想知道這個targt 具體指的是什麼,咱們須要去看一下config配置文件npm

層層遞進

1.scripts\config.js 中咱們能夠找到,最下方爲該文件的js執行部分,其中先去判斷了咱們所傳入的Target,而後調用了genConfigjson

//  判斷傳入的環境變量
if (process.env.TARGET) {
  module.exports = genConfig(process.env.TARGET)
}

2.咱們繼續往上看,genconfig根據函數名咱們能夠得知,爲獲取config這樣的一個功能,Target爲傳入的name,文件的上方定義了 builds,一個屬性對應一個Target*,這樣咱們能夠找到咱們專一的web-full-devsegmentfault

// 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.jsweex

3.打開entry-runtime-with-compiler.js, 在文件上方,咱們能夠看到這個文件中import Vue,咱們所須要的是去追根到Vue的起始,因此就找到了上一層runtime/indexide

// 引入了Vue的實例
import Vue from './runtime/index'

4.打開上一步咱們找到的src/platforms/web/runtime/index.js 文件,第一行就引入了import Vue from 'core/index'
不要緊咱們繼續,酒香不怕巷子深
5.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

下一篇 :Vue源碼學習(二)——從宏觀看Vue

相關文章
相關標籤/搜索