vue init深度定製團隊自己的Vue template

付正義發表於2018-05-25

大家都知道,使用vue-cli可以快速的初始化一個基於Vue.js的專案,全域性安裝腳手架之後,你可以通過vue list命令看到官方提供的5個模板

vue list

當開發一個獨立專案的時候,使用官方提供的template確實很方便,省去了繁瑣的依賴配置,webpack等配置問題,甚至連專案目錄結構也不需要去考慮,著實方便。但是,當我們需要開發多個系統,每個系統依賴的包,webpack都不一致的時候,vue官方提供的模板就顯得捉襟見肘了,這是我們就需要去考慮,能否開發一套自己定製化的template,答案是肯定的,那麼在開始定製之前我們需要了解一些前置知識。

一、前置知識

模板結構 

首先我們瞭解一下模板的主要結構,當我們從githup官網上去看vue官方給們提供的模板結構的時候,發現模板其實很簡單,主要包括兩個部分

  1. template 該目錄用於存放模板檔案,當你執行vue init <templateName> <myProject>的時候,初始化專案檔案目錄結構就來與此
  2. 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外掛的使用本人尚未研究,如果有感興趣的朋友敬請期待,或可以直接去查閱相關資料。

以上就就是定製團隊模板的大概步驟,差不多已經介紹結束了,如果有興趣趕快為自己的團隊定製去吧!!!

 

相關文章