如何自定義自己的vue-cli模板

ws林海峰發表於2019-03-04

自定義自己的vue-cli模板

在使用vue-cli的過程中,常用的webpack模板只為我們提供最基礎的內容,但每次需要新建一個專案的時候就需要把之前專案的一些配置都搬過來,這樣就造成挺大的不方便,如果是作為一個團隊,那麼維護一個通用的模板,我認為是挺有必要的。
例如下面是我常用構建專案的目錄。

src
├─api  //介面
├─assets //圖片
├─components  //公用元件
├─css  //樣式 主要是scss
├─js //第三方以及工具類
├─page  //頁面
├─router //路由
└─store  //vuex複製程式碼

下面說下怎麼自定義自己的vue-cli模板

fork一個自己的模板

github.com/vuejs-templ… fork 一個庫,再提交自己的修改到【自己的分支】,因為我們大部分內容還是在這個基礎上做修改的。

關於vue-cli的原始碼分析可以參考下這個文章從vue-cli原始碼學習如何寫模板

vuejs-templates/webpack目錄如下,

│  .gitignore
│  circle.yml
│  deploy-docs.sh
│  LICENSE
│  meta.js   //該檔案必須匯出為一個物件, 用於定義模板的 meta 資訊
│  package.json
│  README.md
│  test.sh
├─docs  // 一些介紹該模板一些模組的文件
└─template  //模板的內容


D:\work\nodetest\webpack>複製程式碼

meta.js

meta.js主要是定義模板的一些配置, 目前可定義的欄位如下:

  • prompts: 收集使用者自定義資料
  • filters: 根據條件過濾檔案
  • completeMessage: 模板渲染完成後給予的提示資訊, 支援 handlebars 的 mustaches 表示式
  • complete: 模板渲染完成後的回撥函式, 優先於 completeMessage
  • helpers: 自定義的 Handlebars 輔助函式

    prompts

    有用過vue-cli的同學應該有看過下面的這個圖

    image
    image

    看下 prompts的程式碼

     "prompts": {
        "name": {  //專案名
          "type": "string",
          "required": true,
          "message": "Project name"  
        },
        "description": {  
          "type": "string",
          "required": false,
          "message": "Project description",
          "default": "A Vue.js project"
        },
        "author": {
          "type": "string",
          "message": "Author"
        },
        "router": {   
          "type": "confirm",
          "message": "Install vue-router?"
        },
        ...   
     }複製程式碼

    所有的使用者輸入完成之後, template 目錄下的所有檔案將會用 Handlebars瞭解相關的語法點這裡) 進行渲染. 使用者輸入的資料會作為模板渲染時的使用資料,例如,在cmd確認使用router後,那麼main.js就會import router,main.js中原始碼:

    {{#router}}
    import router from './router'{{#if_eq lintConfig "airbnb"}};{{/if_eq}}
    //類似 {{#if_eq lintConfig "airbnb"}};{{/if_eq}}是啟用lint後一些語法的檢查
    
    {{/router}}複製程式碼

    因為開發常用到vuex,我們可以加入vuex,修改meta.js

     "vuex":{
          "type": "confirm",
          "message": "Install vuex?"
        },複製程式碼

    安裝過程中,就會詢問是否安裝vuex

    helper

    上面的if_eq,還有原始碼中的unless_eq是原本vue cli中註冊的那個輔助函式,在vue-cli中的generate.js:

    # vue-cli/lib/generate.js
    
    //...
    
    // register handlebars helper
    Handlebars.registerHelper('if_eq', function (a, b, opts) {
      return a === b
        ? opts.fn(this)
        : opts.inverse(this)
    })
    
    Handlebars.registerHelper('unless_eq', function (a, b, opts) {
      return a === b
        ? opts.inverse(this)
        : opts.fn(this)
    })複製程式碼

    類似的,你也可以自定義一些函式,方便你自己去處理一些資料,在meta.jshelpers物件中可以加入自己的方法,如原始碼中就有註冊一個if_or的方法,你在檔案中就可以用{{#if_or a b}}{{/if_or}}去使用

    "helpers": {
        "if_or": function (v1, v2, options) {
          if (v1 || v2) {
            return options.fn(this);
          }
    
          return options.inverse(this);
        }
      },複製程式碼

    filters

    filters 是根據條件過濾檔案,原始碼:

     "filters": {
        ".eslintrc.js": "lint",
        ".eslintignore": "lint",
        "config/test.env.js": "unit || e2e",
        "test/unit/**/*": "unit",
        "build/webpack.test.conf.js": "unit",
        "test/e2e/**/*": "e2e",
        "src/router/**/*": "router"  //例如上面的 router 為true的時候,就會加入這個目錄
      },複製程式碼

    同樣,這裡我可以加入自己的vuex目錄,當,vuextrue的時候,會匯入這個目錄

    
     "filters": {
        ".eslintrc.js": "lint",
        ".eslintignore": "lint",
        "config/test.env.js": "unit || e2e",
        "test/unit/**/*": "unit",
        "build/webpack.test.conf.js": "unit",
        "test/e2e/**/*": "e2e",
        "src/store/**/*": "vuex",  //加入自己的目錄
        "src/router/**/*": "router"
      },複製程式碼

    然後在main.js引入vuex

    {{#vuex}}  //vuex為true的時候就會寫入這些
    import Vuex from 'vuex'{{#if_eq lintConfig "airbnb"}};{{/if_eq}}
    import store from  './store/store'{{#if_eq lintConfig "airbnb"}};{{/if_eq}}
    Vue.use(Vuex){{#if_eq lintConfig "airbnb"}};{{/if_eq}}
    {{/vuex}}
    
    //store.js 檔案是我寫vuex的入口
    
    new Vue({
      el: '#app',
      {{#router}}
      router,
      {{/router}}
      {{#vuex}}
      store,
      {{/vuex}}
      {{#if_eq build "runtime"}}
      render: h => h(App){{#if_eq lintConfig "airbnb"}},{{/if_eq}}
      {{/if_eq}}
      {{#if_eq build "standalone"}}
      template: '<App/>',
      components: { App }{{#if_eq lintConfig "airbnb"}},{{/if_eq}}
      {{/if_eq}}
    }){{#if_eq lintConfig "airbnb"}};{{/if_eq}}複製程式碼

    還有在template/package.json中也要加入vuex

     "dependencies": {
        "vue": "^2.5.2"{{#router}},
        "vue-router": "^3.0.1"{{/router}}{{#vuex}},
        "vuex": "^2.1.1"{{/vuex}}
    
      },複製程式碼

    後續的話只需要將自己需要的檔案跟資料夾,加入到template/src,例如,我這裡加入一個詢問是否是移動端的,是移動端的話,會引入 lib-flexible.js以及相關配置的scss檔案

      "isMobile":{
            "type": "confirm",
            "message": "is Mobile project?"
        },複製程式碼

    最後,提交到github自己的分支上,就可以使用了

    vue init jamielhf/webpack#template1 name複製程式碼

    github地址

    github.com/jamielhf/we…

    參考:

    vue-cli webpack的配置詳解
    從vue-cli原始碼學習如何寫模板

相關文章