自定義自己的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
odetestwebpack>複製程式碼
meta.js
meta.js
主要是定義模板的一些配置, 目前可定義的欄位如下:
- prompts: 收集使用者自定義資料
- filters: 根據條件過濾檔案
- completeMessage: 模板渲染完成後給予的提示資訊, 支援 handlebars 的 mustaches 表示式
- complete: 模板渲染完成後的回撥函式, 優先於 completeMessage
- helpers: 自定義的 Handlebars 輔助函式
prompts
有用過
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
了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.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
是根據條件過濾檔案,原始碼:"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複製程式碼
github地址
參考: