「 本文主要梳理一下vue代碼的目錄,以及vue代碼構建流程,旨在對vue源碼總體有一個認知,有助於後續對源碼的閱讀。」javascript
01前端
—vue
目錄結構java
上圖是對vue的代碼的全部目錄進行的梳理,其中源碼位於src目錄下,下面對src下的目錄進行介紹。webpack
compilerweb
該目錄是編譯相關的代碼,即將 template 模板轉化成 render 函數的代碼。json
vue 提供了 render 函數,render 函數做用是用來建立 VNode,但在平時開發中,絕大多數狀況下使用 template 來建立 HTML,因此須要將 template模板編譯成 render 函數。小程序
編譯工做既能夠在代碼構建時作,也能夠在客戶端運行時作,但編譯十分消耗性能,因此在項目中建議使用 runtime 版本。微信小程序
coreapi
這部分代碼是 vue 的核心代碼,能夠說是 vue 的靈魂所在,也是咱們要重點學習的源碼。
core目錄又包含以下子目錄。
components -- 內置組件的代碼,即 keep-alive 代碼
global-api -- 全局API代碼,mixin,extend 等 api 在這裏實現
instance -- vue實例化相關代碼,包括初始化,事件,生命週期,渲染等部分的代碼
observer -- 響應式數據相關代碼
util -- 工具方法
vdom -- 虛擬 dom 的代碼。
platforms
platforms下包含兩個子目錄,web 和 weex。
分別表明能夠打包生成在web端使用的 vue 代碼和在native端使用的 weex 代碼。美團開源的開發微信小程序的 mpvue 框架也是在這個目錄下進行拓展的。
經過不一樣平臺的入口就能夠打包出運行在不一樣平臺的版本的 vue 文件,後面代碼構建部分會介紹具體的構建過程。
server
該目錄下是 SSR 相關的代碼。
Vue.js 是構建客戶端應用程序的框架。除了能夠在瀏覽器中輸出 Vue 組件,也能夠將同一個組件渲染爲服務器端的 HTML 字符串,將它們直接發送到瀏覽器,最後將這些靜態標記"激活"爲客戶端上徹底可交互的應用程序。
sfc
咱們平時開發時,都是寫 .vue 文件。sfc 的代碼就是提供一個解析器,把.vue文件代碼解析成一個 javascript 對象。
shared
該目錄下定義了一些公用的工具方法,提供給上面的幾個目錄內代碼使用。
02
—
源碼編譯
vue的源碼按照功能拆分的十分清晰,每一個功能都有單獨的目錄,那麼項目中引用的vue文件是怎麼編譯出來的呢?
首先,咱們看一下編譯輸出的dist目錄。
能夠看到,dist下有10幾種不一樣版本的vue文件,他們是根據不一樣規範(包括 CommonJS規範,ES Module,UMD)和 是否包含編譯器 構建出的不一樣版本。
vue源碼選擇了rollup進行構建,rollup相比於webpack,更加輕量,編譯後的代碼更加乾淨,更適合javascript庫的構建,除了vue之外,像React,Ember,D3,Three.js 以及其餘不少開源庫也選擇了Rollup 進行構建。
下面看一下vue具體構建過程,首先到pakage.json中看下vue編譯執行的命令。
從命令能夠看出,構建命令就是執行 scripts 目錄下 build.js 文件。
下面是 scripts/build.js 核心代碼
從代碼能夠看出,首先經過 script/config.js 文件的getAllBuilds方法獲取配置,而後根據構建命令傳入的參數對配置進行過濾,最後根據過濾後的配置執行build函數,編譯出對應版本的vue文件。
接下來咱們在看一下配置文件 script/config.js 中的 getAllBuilds 是怎麼獲取具體配置的。
能夠看出,getAllBuilds 方法首先經過 Object.keys 拿到 builds 對象全部key的組成的數組,並經過map遍歷執行genConfig方法。下面咱們先看一下builds對象。
能夠看出,builds對象是不一樣版本vue的編譯配置。具體配置項的做用,已經用註釋在代碼中標出。接下來咱們看下genConfig函數作了什麼。
genConfig 經過 key 拿到 builds 中每一個key對應的配置對象,而後根據這個對象從新定義一個 config 對象,這個 config 對象的結構纔是 rollup 配置真正須要的結構。
看了 builds 對象和 genConfig 方法,咱們就知道了 getAllBuilds 的目的,是經過映射把 builds 配置對象轉化成 rollup 所須要的配置數據。
到這裏,咱們就清楚是如何構建出不一樣版本的vue代碼了。
03
—
心得
學習源碼時,不建議按照源碼的順序一行一行的閱讀。首先要抓住主幹,先梳理清楚主要的代碼邏輯,再去仔細閱讀具體的每行代碼。另外按照源碼順序閱讀可能很枯燥,很難堅持下來,能夠先選擇本身感興趣的部分進行學習,最後再串聯起來。