在使用vue-cli的過程當中,經常使用的webpack模板只爲咱們提供最基礎的內容,但每次須要新建一個項目的時候就須要把以前項目的一些配置都搬過來,這樣就形成挺大的不方便,若是是做爲一個團隊,那麼維護一個通用的模板,我認爲是挺有必要的。
例以下面是我經常使用構建項目的目錄。css
src ├─api //接口 ├─assets //圖片 ├─components //公用組件 ├─css //樣式 主要是scss ├─js //第三方以及工具類 ├─page //頁面 ├─router //路由 └─store //vuex
下面說下怎麼自定義本身的vue-cli模板vue
從 https://github.com/vuejs-templates/webpack fork 一個庫,再提交本身的修改到【本身的分支】,由於咱們大部份內容仍是在這個基礎上作修改的。 node
關於vue-cli的源碼分析能夠參考下這個文章從vue-cli源碼學習如何寫模板 webpack
vuejs-templates/webpack
目錄以下,git
│ .gitignore │ circle.yml │ deploy-docs.sh │ LICENSE │ meta.js //該文件必須導出爲一個對象, 用於定義模板的 meta 信息 │ package.json │ README.md │ test.sh ├─docs // 一些介紹該模板一些模塊的文檔 └─template //模板的內容 D:\work\nodetest\webpack>
meta.js
主要是定義模板的一些配置, 目前可定義的字段以下:github
prompts<Object>: 收集用戶自定義數據web
filters<Object>: 根據條件過濾文件vue-router
completeMessage<String>: 模板渲染完成後給予的提示信息, 支持 handlebars 的 mustaches 表達式vuex
complete<Function>: 模板渲染完成後的回調函數, 優先於 completeMessagevue-cli
helpers<Object>: 自定義的 Handlebars 輔助函數
有用過vue-cli
的同窗應該有看過下面的這個圖
看下 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
了
上面的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.js
中helpers
對象中能夠加入本身的方法,如源碼中就有註冊一個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": { ".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目錄,當,vuex
爲true
的時候,會導入這個目錄
"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
https://github.com/jamielhf/webpack/tree/template1