深入Vue - 原始碼目錄及構建過程分析

Fundebug發表於2019-02-19

摘要: Vue原始碼閱讀第一步。

Fundebug經授權轉載,版權歸原作者所有。

本文主要梳理一下vue程式碼的目錄,以及vue程式碼構建流程,旨在對vue原始碼整體有一個認知,有助於後續對原始碼的閱讀。

1. 目錄結構

深入Vue - 原始碼目錄及構建過程分析

上圖是對vue的程式碼的所有目錄進行的梳理,其中原始碼位於src目錄下,下面對src下的目錄進行介紹。

compiler

該目錄是編譯相關的程式碼,即將 template 模板轉化成 render 函式的程式碼。

vue 提供了 render 函式,render 函式作用是用來建立 VNode,但在平時開發中,絕大多數情況下使用 template 來建立 HTML,所以需要將 template模板編譯成 render 函式。

編譯工作既可以在程式碼構建時做,也可以在客戶端執行時做,但編譯十分消耗效能,所以在專案中建議使用 runtime 版本。

core

這部分程式碼是 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

該目錄下定義了一些公用的工具方法,提供給上面的幾個目錄內程式碼使用。

2. 原始碼編譯

vue的原始碼按照功能拆分的十分清晰,每個功能都有單獨的目錄,那麼專案中引用的vue檔案是怎麼編譯出來的呢?

首先,我們看一下編譯輸出的dist目錄。

深入Vue - 原始碼目錄及構建過程分析

可以看到,dist下有10幾種不同版本的vue檔案,他們是根據不同規範(包括 CommonJS規範,ES Module,UMD)和 是否包含編譯器 構建出的不同版本。

vue原始碼選擇了rollup進行構建,rollup相比於webpack,更加輕量,編譯後的程式碼更加乾淨,更適合javascript庫的構建,除了vue以外,像React,Ember,D3,Three.js 以及其他很多開源庫也選擇了Rollup 進行構建。

下面看一下vue具體構建過程,首先到pakage.json中看下vue編譯執行的命令。

深入Vue - 原始碼目錄及構建過程分析

從命令可以看出,構建命令就是執行 scripts 目錄下 build.js 檔案。

下面是 scripts/build.js 核心程式碼*(*下文中漢字註釋部分是為方便理解自己補充的)

深入Vue - 原始碼目錄及構建過程分析

從程式碼可以看出,首先通過 script/config.js 檔案的getAllBuilds方法獲取配置,然後根據構建命令傳入的引數對配置進行過濾,最後根據過濾後的配置執行build函式,編譯出對應版本的vue檔案。(這裡介紹程式碼構建的過程,主要說明vue是怎麼構建出不同版本程式碼的,build方法在此不做分析)

接下來我們在看一下配置檔案 script/config.js 中的 getAllBuilds 是怎麼獲取具體配置的。

深入Vue - 原始碼目錄及構建過程分析

可以看出,getAllBuilds 方法首先通過 Object.keys 拿到 builds 物件所有key的組成的陣列,並通過map遍歷執行genConfig方法。下面我們先看一下builds物件。

深入Vue - 原始碼目錄及構建過程分析

可以看出,builds物件是不同版本vue的編譯配置。具體配置項的作用,已經用註釋在程式碼中標出。接下來我們看下genConfig函式做了什麼。

深入Vue - 原始碼目錄及構建過程分析

genConfig 通過 key 拿到 builds 中每個key對應的配置物件,然後根據這個物件重新定義一個 config 物件,這個 config 物件的結構才是 rollup 配置真正需要的結構。

看了 builds 物件和 genConfig 方法,我們就知道了 getAllBuilds 的目的,是通過對映把 builds 配置物件轉化成 rollup 所需要的配置資料。

到這裡,我們就清楚是如何構建出不同版本的vue程式碼了。

3. 心得

學習原始碼時,不建議按照原始碼的順序一行一行的閱讀。首先要抓住主幹,先梳理清楚主要的程式碼邏輯,再去仔細閱讀具體的每行程式碼。另外按照原始碼順序閱讀可能很枯燥,很難堅持下來,可以先選擇自己感興趣的部分進行學習,最後再串聯起來。

如果喜歡本文請關注公眾號前端小苑,下一篇vue原始碼文章,將為大家介紹 render 函式和 Virtual DOM 。

深入Vue - 原始碼目錄及構建過程分析

相關文章