vue2.X之vue-cli源碼學習

前言

熟悉vue開發的同窗確定對vue-cli不陌生,Vue-cli是一款基於模板化的開發工具,等於就是把別人的項目結構給照搬過來,全部的配置都是暴露出來的,你能夠根據實際狀況去作一些配置的修改,更加靈活自由一點。前段時間也學習了下cli的源碼,特此來記錄下。javascript

常見 npm 包

在正式開始cli源碼以前,先介紹下一些經常使用的npm包vue

  • commander:一款重量輕,表現力和強大的命令行框架,提供了用戶命令行輸入和參數解析強大功能。
  • handlebars:一個 javascript 語義模版庫。能夠利用 Handlebars.registerHelper 方法註冊了一些 helper,這樣就能夠在模板中方便的使用這些 helper
  • metalsmith:靜態網站生成器,能夠用在批量處理模板的場景。它最大的特色就是全部的邏輯都是由插件處理,你只須要將這些插件用 metalsmith 鏈接起來使用便可。
  • chalk:用於修改控制檯字符串的樣式,包括字體樣式(加粗),顏色以及背景顏色等。
  • download-git-repodownload-git-repo 是用於 從 GitHub, GitLab, Bitbucket 下載一個 git 倉庫。
  • consolidateconsolidate 是一個模版引擎整合庫。

vue-init 流程圖

從圖中能夠看出init主要分爲兩步:

  1. 拉取模版
  2. 渲染模版

接下去將根據源碼對每一步進行說明。java

註冊命令

從圖中能夠看出vue-init的使用方法爲vue-init template-name project-name。同時他提供了-c和--offline這兩個選項。其中-c表明是利用git拉取模版,--offline使用緩存的模板,位於~/.vue-templates目錄下面。

輸入命令後,會利用commend包來分別讀取模版名稱,文件名,以及選項,並根據選項來進行後續的模版拉取操做,從代碼中能夠看到。本地存儲模版的路徑爲根目錄下的.vue-templates文件夾。

這段代碼的做用是:

  1. 若是沒有填寫 app-name ,則默認在當前目錄生成模版。
  2. 若是當前目錄有與 app-name 重名的,是否要繼續。 而後根據用戶的回答執行run函數來拉取模版及渲染模版到目錄中。

拉取模版

咱們來看一下run函數webpack

run函數會先判斷是不是本地模版,若是是,會判斷是否存在,存在則調用generate函數進行渲染,不存在則提醒。 若是不是本地模版,則判斷是不是官方模版進行路徑及版本的判斷,再調用 downloadAndGenerate方法。

downloadAndGenerate會先判斷本地是否存在模版,若是存在則刪除,在調用download方法。

download方法主要根據選項clone來判斷是調用git仍是http方法去下載模版,下載成功後執行回調 generate函數進行模版的渲染。

模版渲染

總體來看 generate函數仍是比較晦澀難懂的,接下來,咱們對這個方法分塊來閱讀。 首先來看 getOption方法

getOption中會先從模版的 template文件夾中的 meta.json或者 meta.js來讀取配置,以後對你輸入的文件名進行驗證,同時添加些默認的配置。其中 meta.jsonmeta.js是動態加載模版的關鍵。

截取webpack模版中的meta.js,其中的message和default是否以爲很熟悉。

接着經過metalsmith獲取模版下的template文件夾作爲後續的文件模版。再經過 Handlebars.registerHelper註冊邏輯命令,從而處理一些數據,像webpack中就註冊了if_eq來判斷是否相等。

註冊完命令以後會執行 meta.js中的before函數,webpack中的方法爲 addTestAnswers

metalsmith.before 結果就是將 metalsmith metadata 數據和 isNotTest 合併,若是 isTest 爲 ture,還會自動設置 name,description等字段。它的做用就是爲模版添加自動測試腳本,它會將 isNotTest 設置爲 false,而經過 inquirer 來提問又會是在 isNotTest 爲 true 的狀況下才會發生,所以設置了VUE_TEMPL_TEST的值會省略 inquirer 提問過程,而且會根據你設置的值來生成對應的模板,有如下三種值能夠設置:

  1. minimal:這種不會設置 router,eslint 和 tests
  2. full: 會帶有 router,eslint (standard) 和 tests (jest & e2e)
  3. full-airbnb-karma:帶有 router eslint(airbnb) 和 tests(karma) 具體的使用方式:
VUE_TEMPL_TEST=full vue init webpack demo
複製代碼

調用完before函數後會調用 metalsmith.use來使用 askQuestionfilterFilesrenderTemplateFiles這三個插件。下面逐個來看這三個插件是幹啥的。 askQuestion調用了 ask函數。

ask函數就是經過 inquirer.prompt 來實現命令行交互,並將交互的值經過 metalsmith.metadata() 存到全局,而後在渲染模板的時候直接獲取這些值。

filterFiles則是經過用戶的回答將一些須要過濾調的文件刪除

renderTemplateFiles 的主要功能就是利用 consolidate.handlebars.render~/.vue-templates下面的 handlebars 模板文件渲染成正式的文件。

以後執行 afterbuild函數完成整個渲染流程。

結語

至此,vue-init的整個流程及源碼就結束了,其實總體流程仍是比較清晰的,經過對次源碼的學習咱們在往後能夠構建本身的腳手架和模版。畢竟懶惰是第一輩子產力!git

相關文章
相關標籤/搜索