在使用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