我来简单说一下我的见解吧,有些简单浅显(小学语文真的没学好),目的在于提供一个思路供大家参考。
项目类型
前端的项目目前来看主要分为小程序开发,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三种风格,在项目搭建时这也是一个很重要的技术选型。
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
目录中
权限配置
主要分为页面权限(路由)、功能权限,采用多级角色划分方式。菜单配置数据直接通过接口返回