大家都知道,使用vue-cli可以快速的初始化一個基於Vue.js的專案,全域性安裝腳手架之後,你可以通過vue list命令看到官方提供的5個模板
vue list
當開發一個獨立專案的時候,使用官方提供的template確實很方便,省去了繁瑣的依賴配置,webpack等配置問題,甚至連專案目錄結構也不需要去考慮,著實方便。但是,當我們需要開發多個系統,每個系統依賴的包,webpack都不一致的時候,vue官方提供的模板就顯得捉襟見肘了,這是我們就需要去考慮,能否開發一套自己定製化的template,答案是肯定的,那麼在開始定製之前我們需要了解一些前置知識。
一、前置知識
模板結構
首先我們瞭解一下模板的主要結構,當我們從githup官網上去看vue官方給們提供的模板結構的時候,發現模板其實很簡單,主要包括兩個部分
- template 該目錄用於存放模板檔案,當你執行vue init <templateName> <myProject>的時候,初始化專案檔案目錄結構就來與此
- meta.js/meta.json用於描述初始化專案的時候在命令列和使用者互動的行為
download-git-repo
使用vue-cli初始化專案時會使用該工具來下載目標倉庫,預設我們平常都會下載webpack這個模板(vue init webpack myProject),自定義模板可以是一個GitHub倉庫,也可以是一個本地檔案,使用如下命令來初始化專案:
vue init username/repo my-project //其中username為自定義模板倉庫所在GitHub使用者名稱,repo是倉庫名
vue init ./../ my-project //本地檔案
Inquirer.js
vue-cli在模板倉庫下載完成後,將通過Inquire.js根據模板倉庫中的meta.js或meta.json檔案中的設定,與使用者進行一些簡單的互動以確定專案的一些細節,如下圖:
該互動是可選的,如果專案中沒有meta.js或meta.json檔案時,模板倉庫下載完成後將直接進入模板模板構建過程。
Handlebars.js
在通過命令列互動確定了專案初始化細節後,就該進入最後一道工序,按照模板初始化我們的專案了,這裡vue-cli選用的是Handlebars.js,一個簡單高效的語義化模板構建引擎。
定製模板主要圍繞著命令列互動(Inquirer.js)與模板檔案開發(Handlebars.js)這兩部分。
meta.js配置檔案(Inquirer.js)
meta.js相當於模板專案的配配置檔案,這個檔案不是必須的,這裡主要看看它能做些什麼,設定都在meta.js或meta.json裡面,但是我推薦使用meta.js,因為它的配置相對更靈活一點,下面主要簡單說明一下meta.js的配置。
meta.js一共包含如下幾個欄位,簡單列一下各欄位功能:
-
- helpers:自定義Handlebars.js的輔助函式
- prompts:基於Inquirer.js的命令列互動配置
- filters:根據命令列互動結果過濾將要渲染的專案檔案
- metalSmith:配置Metalsmith外掛,檔案會像gulp.js中的pipe一樣依次經過各個外掛的處理
- completeMessage:將模板渲染為專案後輸出一些提示資訊,取值為字串
- complete:與completeMessage功能相同,二選其一,取值為函式,函式最後要返回輸出的字串,這裡也可以配置讓其自動安裝專案依賴
命令列互動(Inquirer.js)
命令列互動主要是meta.js中prompts欄位的配置,詳細的配置可以閱讀官方文件,或者在這裡推薦我一個朋友的部落格地址,他那有詳細的說明。
module.exports = { metalsmith:{ before: addTestAnswers },
"helpers": { "if_or": function (v1, v2, options) { if (v1 || v2) { return options.fn(this); } return options.inverse(this); }, template_version() { return templateVersion }, }, "prompts": { "name": { "type": "input", "required": true, "message": "專案名" }, "author": { "type": "input", "message": "作者" }, } }
說一下各個欄位的意思
-
- name與author:互動欄位名稱,可在後續條件互動或模板渲染時通過該欄位讀取到互動的的結果。
- type:互動型別,有input,confirm,list,rawlist,expand,checkbox,password,editor八種型別
- message:互動的提示資訊
- when:進行該條件互動的先決條件
- default:預設值,當輸入為空時預設此值
- required:預設為false,該值是否為必填項
- validate:輸入驗證函式
模板基本語法(Handlebars.js)
在編寫模板的時候,我們可以用Mustache語法在任何文字型別的檔案中輸出在命令列互動中得到一些資料:
{ "name": "{{ name }}", "description": "{{ description }}", "scripts": { "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", "start": "npm run dev", {{/if_eq}} {{#e2e}} "e2e": "node test/e2e/runner.js",{{/e2e}} {{#if_or unit e2e}} "build": "node build/build.js" }, "dependencies": { {{#vux}} "vux": "^2.2.0", {{/vux}} } }
以package.json檔案為例,{{name}}即為meta.js裡面寫name,{{#vux}}”vux”:”^2.2.0″,{{/vux}}即為根據命令列互動的結果得知是否渲染。
模板渲染時的輔助函式(Handlebars.js)
vue-cli中為handlebar.js預置了if_eq與unless_eq輔助函式,用於使用互動所得資料來處理模板中是否渲染兩種邏輯關係,此外handlebars中還內內建了if、unless、each等輔助函式。此外我們可以自定義輔助函式(handlebars.js)
有時候現有的輔助函式不能可能不能滿足我們的需求,通過meta.js中的helpers欄位我們可以自定義輔助函式:
"helpers": { "if_or": function (v1, v2, options) { if (v1 || v2) { return options.fn(this); } return options.inverse(this); }, template_version() { return templateVersion }, },
輔助函式可以接受若干個引數,最後一個引數options為輔助函式的鉤子,呼叫options.fn(this)即輸出該輔助函式運算結果為真時的內容,反之呼叫options.inverse(this)的內容
現在就可以直接再模板中使用if_or輔助函式了:
{{#if_or unit e2e}} "test": "{{#unit}}npm run unit{{/unit}}{{#unit}}{{#e2e}} && {{/e2e}}{{/unit}}{{#e2e}}npm run e2e{{/e2e}}", {{/if_or}}
按條件過濾渲染檔案
輔助函式值可以控制檔案內的一部分內容的輸出與否,有時候我們需要根據互動結果控制某些檔案本身是否輸出。
在meta.js中的filters欄位中進行相應的設定就可以達到控制檔案輸出的效果
filters: {//根據命令列互動的結果過濾將要渲染的專案檔案 `.eslintrc.js`: `lint`, `.eslintignore`: `lint`, `config/test.env.js`: `unit || e2e`, `build/webpack.test.conf.js`: "unit && runner === `karma`", `test/unit/**/*`: `unit`, `test/unit/index.js`: "unit && runner === `karma`", `test/unit/jest.conf.js`: "unit && runner === `jest`", `test/unit/karma.conf.js`: "unit && runner === `karma`", `test/unit/specs/index.js`: "unit && runner === `karma`", `test/unit/setup.js`: "unit && runner === `jest`", `test/e2e/**/*`: `e2e`, `src/router/**/*`: `router`, },
filters中鍵名是要控制輸出的檔案的路徑,鍵名對應的值為命令列互動中得到的資料
關於metalSmith外掛的使用本人尚未研究,如果有感興趣的朋友敬請期待,或可以直接去查閱相關資料。
以上就就是定製團隊模板的大概步驟,差不多已經介紹結束了,如果有興趣趕快為自己的團隊定製去吧!!!