项目类型
前端的项目目前来看主要分为小程序 开发,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
目录中
权限配置
主要分为页面权限(路由)、功能权限,采用多级角色划分方式。菜单配置数据直接通过接口返回
原文出自:https://github.com/haizlin/fe-interview/issues/983#issuecomment-546895784
转载仅作记录,方便自己查阅