自定義自己的vue-cli模板
在使用vue-cli的過程中,常用的webpack模板只為我們提供最基礎(chǔ)的內(nèi)容,但每次需要新建一個(gè)項(xiàng)目的時(shí)候就需要把之前項(xiàng)目的一些配置都搬過來,這樣就造成挺大的不方便,如果是作為一個(gè)團(tuán)隊(duì),那么維護(hù)一個(gè)通用的模板,我認(rèn)為是挺有必要的。
例如下面是我常用構(gòu)建項(xiàng)目的目錄。
src
├─api //接口
├─assets //圖片
├─components //公用組件
├─css //樣式 主要是scss
├─js //第三方以及工具類
├─page //頁面
├─router //路由
└─store //vuex
下面說下怎么自定義自己的vue-cli模板
fork一個(gè)自己的模板
從 https://github.com/vuejs-templates/webpack fork 一個(gè)庫,再提交自己的修改到【自己的分支】,因?yàn)槲覀兇蟛糠謨?nèi)容還是在這個(gè)基礎(chǔ)上做修改的。
關(guān)于vue-cli的源碼分析可以參考下這個(gè)文章從vue-cli源碼學(xué)習(xí)如何寫模板
vuejs-templates/webpack目錄如下,
│ .gitignore
│ circle.yml
│ deploy-docs.sh
│ LICENSE
│ meta.js //該文件必須導(dǎo)出為一個(gè)對象, 用于定義模板的 meta 信息
│ package.json
│ README.md
│ test.sh
├─docs // 一些介紹該模板一些模塊的文檔
└─template //模板的內(nèi)容
D:\work\nodetest\webpack>
meta.js
meta.js主要是定義模板的一些配置, 目前可定義的字段如下:
- prompts<Object>: 收集用戶自定義數(shù)據(jù)
- filters<Object>: 根據(jù)條件過濾文件
- completeMessage<String>: 模板渲染完成后給予的提示信息, 支持 handlebars 的 mustaches 表達(dá)式
- complete<Function>: 模板渲染完成后的回調(diào)函數(shù), 優(yōu)先于 completeMessage
- helpers<Object>: 自定義的 Handlebars 輔助函數(shù)
prompts
有用過vue-cli的同學(xué)應(yīng)該有看過下面的這個(gè)圖

看下 prompts的代碼
"prompts": {
"name": { //項(xiàng)目名
"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 目錄下的所有文件將會(huì)用 Handlebars(了解相關(guān)的語法點(diǎn)這里) 進(jìn)行渲染. 用戶輸入的數(shù)據(jù)會(huì)作為模板渲染時(shí)的使用數(shù)據(jù),例如,在cmd確認(rèn)使用router后,那么main.js就會(huì)import router,main.js中源碼:
{{#router}}
import router from './router'{{#if_eq lintConfig "airbnb"}};{{/if_eq}}
//類似 {{#if_eq lintConfig "airbnb"}};{{/if_eq}}是啟用lint后一些語法的檢查
{{/router}}
因?yàn)殚_發(fā)常用到vuex,我們可以加入vuex,修改meta.js
"vuex":{
"type": "confirm",
"message": "Install vuex?"
},
安裝過程中,就會(huì)詢問是否安裝vuex了
helper
上面的if_eq,還有源碼中的unless_eq是原本vue cli中注冊的那個(gè)輔助函數(shù),在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)
})
類似的,你也可以自定義一些函數(shù),方便你自己去處理一些數(shù)據(jù),在meta.js中helpers對象中可以加入自己的方法,如源碼中就有注冊一個(gè)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 是根據(jù)條件過濾文件,源碼:
"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的時(shí)候,就會(huì)加入這個(gè)目錄
},
同樣,這里我可以加入自己的vuex目錄,當(dāng),vuex為true的時(shí)候,會(huì)導(dǎo)入這個(gè)目錄
"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的時(shí)候就會(huì)寫入這些
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}}
},
后續(xù)的話只需要將自己需要的文件跟文件夾,加入到template/src,例如,我這里加入一個(gè)詢問是否是移動(dòng)端的,是移動(dòng)端的話,會(huì)引入 lib-flexible.js以及相關(guān)配置的scss文件
"isMobile":{
"type": "confirm",
"message": "is Mobile project?"
},
最后,提交到github自己的分支上,就可以使用了
vue init jamielhf/webpack#template1 name
github地址
https://github.com/jamielhf/webpack/tree/template1