从0到1自己构架一个vue项目,说说有哪些步骤、哪些重要插件、目录结构你会怎么组织
-
vue-cli实际上已经很成熟了,目录除了脚手架默认的,
1、一般会额外创建views,components,api,utils,stores等;
2、下载重要插件,比如axios,dayjs(moment太大),其他的会根据项目需求补充;
3、封装axios,统一api调用风格和基本配置;
4、如果有国际化需求,配置国际化;
5、开发,测试和正式环境配置,一般不同环境API接口基础路径会不一样; -
- 安装node.js
- 安装vue:npm install vue -g
- 安装webpack:npm install webpack -g
- 安装vue-cli:npm install vue-cli -g
构建项目: vue init webpack 文件名
-
我来简单说一下我的见解吧,有些简单浅显(小学语文真的没学好),目的在于提供一个思路供大家参考。
项目类型
前端的项目目前来看主要分为小程序开发,H5页面开发、PC官网、后台管理系统开发、Native开发。不同的项目所涉及的知识点和环境不太一样,但是很多方面是相通的。
- 小程序
由于框架限定在Vue,所以这里指的是使用mpvue、WePY来开发小程序项目。
- H5页面
这里主要是指微信页面、Webview中的H5页面开发
- PC官网
为什么单独划出来是因为官方的开发主要是用来展示企业信息、产品,对交互、体验有一定的要求,会有一些炫酷的动画效果。还有就是官网有可能需要采用SSR(比如Vue的Nuxt.js)来做,来确定良好的SEO。
- 后台管理系统
后台管理系统主要功能在于数据的配置、权限的控制、数据报表的展示、日志功能等。通常又叫CMS,OA。
- Native开发
这个通常就是指用前端技术去开PC应用、APP应用,比如Weex, Electron。
- 通吃型
比如uni-app, 可以一套代码编译成不同的平台源码。
不同的项目类型决定了其能够使用的生态、目录结构、特定的上下文。这里就以后台管理系统为例来说一下如何基于Vue来搭建一个项目。
注: 我只会玩这个,凑合阅读吧
基于@vue/cli的选型
后台管理系统中
vue-router
,vuex
都是必选的,其它可以自行考虑。-
ES6/7 or Typescript ?
鉴于目前Typescript如此流行,很多流行的框架和库都采用其来写,IDE友好的智能提示、强类型结束等,在立项时是否考虑采用Typescript来写Vue项目。如果采用Typescript,是不是很羡慕Angular中的DI注入,那可以考虑在大型项目中引入inversify这个库;在开发过程中遇到一些库没有声明文件要学会定义声明文件,这个是Typescript初学者最头疼的问题。还有一个问题是团队中有多少人会Typescript,项目周期紧不紧,有没有时间来试错,踩坑。
-
Sass/Less/Stylus/PostCss ?
由于Vue项目开发本身样式自带scope
,所以不需要像React那样去选css-in-js框架(目前在React最流行的是styled-components
),但是如果我们在Vue中采用JSX的方式来定义组件,是否考虑引入vue-styled-components
这个库(年久失修,完全脱节React版了,但依然是Vue中最好的选择)。在Vue中sass, less, stylus可以在<style>
标签中通过lang=""
来指定,如果你想使用PostCss
也可以的,就是要自己花点时间去折腾一下。 -
关于代码规范和风格
这个主要的选择就是Prettier 和 Airbnb风格,如果配置不好,在IDE中满屏的红色波浪线和黄色的小灯光提示。
在配置eslint或者tslint时主要考虑的点是是否要写分号,未定义变量等问题。
-
关于测试
很多时间前端项目测试反而拖慢了项目的开发进度,但是在开源项目中良好的测试是保证项目质量的一个很重要方式。这里通常分为单元测试(Unit Testing)和端到端测试(E2E Testing),更多信息我也没有什么经验,自行百度、Google。
通过 @vue/cli 生成项目后,接下来就是添加一些配置文件
通用配置
一个前端项目在开发过程中少不了各种框架、IDE的配置文件。前端项目的配置文件通常格式有
xx.json
、.xxrc
、xx.config.js
、xxconfig
等方式。- 编辑器配置:
.editorconfig
这里最重要的是缩进方式,及Tab大小,建议2个空格作用缩进。
# https://editorconfig.org root = true [*] charset = utf-8 indent_style = space indent_size = 2 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true [*.md] insert_final_newline = false trim_trailing_whitespace = false
- Git忽略文件配置:
.gitignore
这里的配置决定了哪些文件会被版本控制所忽略
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # dependencies /node_modules /.pnp .pnp.js # testing /coverage # production /build # misc .DS_Store .env.local .env.development.local .env.test.local .env.production.local npm-debug.log* yarn-debug.log* yarn-error.log* # editor /.idea
- Eslint配置:
.eslintrc.js
,.eslintignore
等
说实话eslint要是配置不好,代码在IDE中提示真的很恶心,但是配置项又太多,还有很多专有的扩展,这里给出我的一个配置(也是到处copy过来的)
module.exports = { root: true, env: { node: true }, extends: ["plugin:vue/strongly-recommended"], rules: { "no-console": process.env.NODE_ENV === "production" ? "error" : "off", "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off", // 不加分号 "semi": [0], // 不能有未定义的变量 "no-undef": 1, // 不能有声明后未被使用的变量或参数 "no-unused-vars":[2, { "vars": "local", "args": "none" }], // 禁止修改const声明的变量 "no-const-assign": 2, // 函数参数不能重复 "no-dupe-args": 2, // 如果if语句里面有return,后面不能跟else语句 "no-else-return": 2, // 块语句中的内容不能为空 "no-empty": 2, // 禁止对null使用==或!=运算符 "no-eq-null": 2, // 禁止扩展native对象 "no-extend-native": 2, // 禁止不必要的函数绑定 "no-extra-bind": 2, // 禁止非必要的括号 "no-extra-parens": 2, // 禁止多余的冒号 "no-extra-semi":2, // 禁止省略浮点数中的0 .5 3. "no-floating-decimal": 2, // 禁止行内备注 "no-inline-comments": 0, // 不能有不规则的空格 "no-irregular-whitespace": 2, // 不能用多余的空格 "no-multi-spaces": 1, // 禁止重复声明变量 "no-redeclare": 2, // 禁止使用javascript:void(0) "no-script-url": 0, // 禁止稀疏数组, [0,,2] "no-sparse-arrays": 2, // 禁止使用三目运算符 "no-ternary": 0, // 一行结束后面不要有空格 "no-trailing-spaces": 1, // 标识符不能以_开头或结尾 "no-underscore-dangle": 1, // 是否允许非空数组里面有多余的空格 "array-bracket-spacing": [2, "never"], // 箭头函数用小括号括起来 "arrow-parens": 0, // =>的前/后括号 "arrow-spacing": 0, // 块语句中使用var "block-scoped-var": 0, // 逗号风格,换行时在行首还是行尾 "comma-style": [2, "last"], // 避免不必要的方括号 "dot-notation": [0, { "allowKeywords": true }], // 必须使用全等 "eqeqeq": 2, // 对象字面量中冒号的前后空格 "key-spacing": [0, { "beforeColon": false, "afterColon": true }], // 变量声明后是否需要空一行 "newline-after-var": 0, // 引号类型 `` "" '' "quotes": [1, "single"], // 变量声明时排序 "sort-vars": 0, // 禁止比较时使用NaN,只能用isNaN() "use-isnan": 2, //jsx中使用单引号 "jsx-quotes": ["error", "prefer-single"], // 单个组件无内容自结尾 "vue/html-self-closing": ["error", { "html": { "void": "always", "normal": "always", "component": "always" }, "svg": "always", "math": "always" }], // 设置html缩进 "vue/html-indent": ["error", 2, { "attribute": 2, "baseIndent": 1, "closeBracket": 0, "alignAttributesVertically": false, "ignores": [] }], // 属性顺序 "vue/attributes-order": 1, // 注释前面需要添加空格 "spaced-comment": ["error", "always", { "exceptions": ["-", "+"] }], // html属性赋值等号左右不能有空格 "vue/no-spaces-around-equal-signs-in-attribute": ["error"], // 强制prop以驼峰命名 "vue/prop-name-casing": ["error", "camelCase"], // 移除多余不使用的空格 "vue/no-multi-spaces": ["error", { "ignoreProperties": false }], // html结尾 > "vue/html-closing-bracket-newline": ["error", { "singleline": "never", "multiline": "never" }], // 属性每行数量 "vue/max-attributes-per-line": ["error", { // 一行最多3个属性 "singleline": 3, "multiline": { "max": 1, "allowFirstLine": true } }], // 单行html元素内容是否换行 "vue/singleline-html-element-content-newline": ["error", { "ignoreWhenNoAttributes": true, "ignoreWhenEmpty": true, "ignores": [ "pre", "textarea", "span", "i", "label", "el-button", "el-radio", "el-checkbox", "el-link", "el-tab-pane", "el-dropdown-item", "el-step", "el-table-column", "el-option" ] }] }, parserOptions: { parser: "babel-eslint" } };
- PostCss配置:
postcss.config.js
这个文件自动生成,里面的内容就是指定
autoprefixer
兼容配置- Babel配置:
babel.config.js
主要是配置Babel的
plugins
、presets
和parse
等- StyleLint:
.stylelintrc
如果代码对样式有一定的规范的话,可以加一个,没有就不需要配置这个。
{ "extends": "stylelint-config-standard", "plugins": ["stylelint-scss"] }
- @vue/cli配置:
vue.config.js
在这个里面我们可以对@vue/cli的Webpack进行配置和覆盖。
module.exports = { devServer: { proxy: { '/kpi': { target: process.env.VUE_APP_KPI_API, changeOrigin: true } } } }
- Webpack配置:
webpack.config.js
因为在webpack中不能识别@vue/cli中的
@
路径,所以需要一个配置文件让webapck提示正常。具体怎么配置可以自行搜索。'use strict' const path = require('path') function resolve (dir) { return path.join(__dirname, '.', dir) } module.exports = { context: path.resolve(__dirname, './'), resolve: { extensions: ['.js', '.vue', '.json'], alias: { '@': resolve('src'), '_c': resolve('src/components') } } }
- Visual Studio Code配置:
.vscode
目录
这里主要是配置基于vscode的代码调试以及eslint配置。
版本控制
不管是多人协作开发还个一个人开发在使用git时都需要一套流程规范来执行。
- Git Flow
这个每个团队的做法不太一样,有的采用多分支开发,有的采用单一master分支开发,有的还采用submodule的方式,有的在项目中使用了lerna来做多packages,甚至有的公司一个分支一个项目。
在开发环境的区分上通常分为生产(线上)环境、预发布环境、开发环境,有的还有什么沙盒环境,很多做得好的公司基于Docker前后端都可以根据每一个commit来发布。
有时候不想把有些代码提交上去,除了选择性提交单个文件外,还有使用git的
stash
功能,此外如果使用Webstorm可还可以使用其提供的Changelist来缓存修改,切换分支。- Git Commit
项目提交的描述如果没有一定的规范,随性而为的话,就会让其它人误解。通常提交采用英文作为描述,可以多行文字。在社区中有很多流行的方案(比如Conventional Commit),更多的是采用Angular的方式。
- Change Log
如果采用了社区统一的commit方式,那么我们就可以基于提交来生成变更记录,在每一次版本发布时自动关联Jira中的Issue。
- 版本号生成
这个通常是按照Semantic Versioning的规范来打tag,具休怎么做可以自行尝试
在项目中通常使用
gitHooks
和husky
这二个node包来配置上面提到的这些。在git钩子中我们在每次提交、push前跑一次单元测试、代码覆盖率。前端代码覆盖率一般来说没有必要加,不然很痛苦。下面是
package.json
文件中相关的配置示例(试验性代码){ "name": "your-project-name", "version": "0.1.0", "scripts": { "clean": "rm -rf node_modules", "serve": "vue-cli-service serve", "build": "vue-cli-service build", "lint": "vue-cli-service lint --no-fix", "stylelint": "stylelint src/**/*.{scss,css,less,css,vue,jsx} --fix", "eslint": "eslint --ext .js,.jsx,.vue src --fix", "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0" }, "repository": { "type": "git", "url": "http://gitlab.transsion.com/mi/mi-bigdata-admin.git" }, "dependencies": {}, "devDependencies": { "@commitlint/cli": "^8.1.0", "@commitlint/config-conventional": "^8.1.0", "babel-eslint": "^10.0.1", "conventional-changelog-cli": "^2.0.23", "eslint": "^6.2.1", "eslint-plugin-vue": "^5.2.3", "husky": "^3.0.4", "lint-staged": "^9.2.3", "stylelint": "^10.1.0", "stylelint-config-standard": "^18.3.0", "stylelint-scss": "^3.9.4", }, "gitHooks": { "pre-commit": "lint-staged" }, "lint-staged": { "*.{js,vue}": [ "vue-cli-service lint", "eslint --fix --ext .js,.vue src", "git add" ], "*.{css,scss,less,vue}": [ "stylelint --fix", "git add" ] }, "husky": { "hooks": { "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" } } }
项目文档和组件测试文档
除了在项目根目录放一个
README.MD
文件外,通常还需要一些比如CHANGELOG.md
,PLAD.md
等文档,还有一些组件的使用文档,可以考虑使用styleguide
和storybook
。持续集成和部署
目前开源项目通常采用Travis,而一般公司内部项目通常采用Jenkins来做持续集成,在部署上通常采用Docker,集群上使用KubeOperator来管理。
## API请求方式
通常采用Restfull的方式来请求数据,也可以采用GraphQL的方式来请求。如果采用Restfull的方式通常可以使用
axios
,fetch api
。GraphQL可以使用Apollo Client。代理和数据Mock
SPA页面开发通常都是配置代码来调用后端的接口数据,怎么配置可以参考@vue/cli文档。数据Mock主要用到一个
mockjs
,至于怎么起服务自行搜索。项目用到的库
下面这些库可以在所有项目中使用
注:UI风格目前有Bookstrap、Antd和Google Materials三种风格,在项目搭建时这也是一个很重要的技术选型。
-
日期: moment, dayjs
-
URL解析: query-string, path-to-reqexp
-
实用方法: lodash
-
Cookie: js-cookie
-
混淆ID: hashids
-
图表: echarts
-
Ajax: axios, isomorphic-fetch, vue-apollo
-
拖拽: Vue.Draggable
-
Meta修改: vue-meta
注:这些只是我能想到的
项目目录划分
- 视图页面放在
pags
或者views
中 - 静态文件放在
static
中 - 资源文件放在
assets
中 - 样式文件放在
styles
中 - 辅助库放在
utils
中 - 配置文件可以放在
config
或者constants
中 - vuex的文件放在
stores
中,至于getters, actions, mutation, modules可以参考vuex的文档 - 路由文件放在
routes
中 - 所有组件放在
components
中 - 共享代码也可以使用
shared
作为目录 - 布局组件可以放在
layouts
目录中
权限配置
主要分为页面权限(路由)、功能权限,采用多级角色划分方式。菜单配置数据直接通过接口返回
最后
由于回答比较仓促,项目中很多细节并没有展开说明(展开估计要长篇大论,也不一定能说清楚)。忙着下班,所有以后面就没有章法的乱写了,我平时也很少写东西,很多知识点还是多去参考一下一些不错的文章来学习吧。
最后欢迎光顾我的半年不更新的博客: jenemy
-
目前經驗偏向中小型專案,在架構項目前通常會花一些時間做預先的規劃。
規劃
一開始會先依照需求以及設計圖列出此次的開發項目,並在開始專案前將各個功能依據重要性分級,排定開發的順序,若是有不熟悉的功能則會規劃時間學習。
在確認需要開發的功能以及邏輯後,思考流程,以及與後端確認頁面所需求的資料,並且共同討論頁面 API 該如何規劃。預先規劃出每個頁面的 component、共用 component 名稱、切分範圍,component 負責呈現資料以及包含一些組件的邏輯功能、views 則管理該頁面的資料。
事前規劃都告一段落後,接著便可以構建架構,會透過 Vue-cli 建構(自己從頭建立太苦啦),創建時會選擇以下插件:
- css-preprocesser - dart-sass
- lint - standard
- vuex - 管理 api 資料
- vue-router - 路由管理
開發
接著建好專案後,通常會依照需求裝入以下插件:
- svg-loader - 將 svg 作為組件使用
- axios
- dayjs - 以往常用的 moment.js 除了既有舊專案外,構建團隊今年中建議改採其他更為輕量的 library
- bootstrap-vue 看設計稿,如果是需要手刻的就偏向引入頁面結構組件如
b-row
專案目錄大致如下,將剛剛預先規劃的 component、views 先建立好,接著便可以開始切分組件 css:
src ├── App.vue ├── assets │ ├── img │ │ ├── access_time-24px.svg │ │ ├── accessibility_new-24px.svg │ │ ├── add_circle_outline-24px.svg │ │ ├── alarm.svg │ │ ├── apps-24px.svg │ └── scss │ ├── abstracts │ ├── base │ ├── main.scss │ └── plugin ├── components │ ├── Base │ │ ├── BaseCard.vue │ │ ├── BaseCol.vue │ │ ├── BaseLoadCard.vue │ │ ├── BaseRow.vue │ │ └── FlexSystem.md │ ├── Home │ │ ├── HomeChart.js │ │ ├── HomeItem.vue │ │ ├── HomeNavbar.vue │ │ ├── HomeSideBar.vue │ │ └── HomeSortbar.vue │ └── Information │ └── InformationChart.js ├── main.js ├── router │ └── index.js ├── service │ ├── api.js │ └── dayFormate.js ├── store │ └── index.js └── views ├── Home.vue └── Information.vue
頁面路由及組件樣式切分完成,接著便可以開始開發功能以及串接資料。
-
1、整个项目需求分析,按需求确定基本的技术栈,以及整体逻辑。
2、vue-cli 脚手架搭建,涉及到webpack,如有脚手架不满足的需求,需要做调整,如项目环境在域名的二级目录,图片、字体路径修改等。
3、开发、测试、预发布、正式环境配置,以及package.json script 脚本补充。
4、涉及到https,需要兼容http。
5、增加目录:assets、layouts 、api、component、libs、plugin、router、store。(有本地mock习惯的加上mock目录),store内部目录划分。
6、安装必须的库并引入,例如ui框架、babel、axios, 写好axios 拦截组件。
7、写好或copy常用的小插件,比如时间转换、cookie设置获取、千分位设置、邮箱校验等
8、git 工作流程梳理以及版本发布注意事项。
9、.editorconfig配置、 .gitignore 配置, readme 书写
以上基本是我工作几年的经验。 -
要看是vue.js还是vue cli项目,如果是vue.js可以按照普通web项目流程开发,只在代码架构上变为数据和模型分离的模式即可。
如果是vue cli项目,不仅要分离数据和模型,还要理解vue router, vuex等组件,并且对于组件化的概念要更加透彻,由其是单页面应用,每个子页面如何组件化是必须在项目伊始就想清楚的。