技术选型
Vue 与 React 的对比
- 组件化
Vue 的组件化是将 UI 结构(template)、UI 样式(style)、数据与业务逻辑(script)都放在一个 .vue 的文件中,运行前 .vue 文件会被编译成真正的组件;
React 的组件化是直接通过 JS 代码的形式实现组件 - 模板引擎
Vue的视图模板使用类 HTML 的写法加上属性与指令,多数情况下要比 React 的 JSX 写法清晰且开发效率高,但是在复杂场景下,Vue 的写法有时会比 React 写起来更麻烦 - 数据监听
Vue 使用代理/拦截的方式使得我们直接修改 data 就可以,但 React 需要使用 setState API 改变数据
项目构建
目录结构
├─ mock #数据模拟
├─ public #静态
├─ scripts #脚本
└─ src
├─ common #工具库
├─ components #组件
├─ hooks #钩子
├─ pages #页面
├─ styles #样式
└─ router #路由
技术栈
- 开发框架:
React
- 构建工具:
Webpack
- 类型检查:
TypeScript
- 日志埋点:
@baidu/bend-sdk
- 视图样式:
styled-components
- 状态管理:
React-hook/useReducer
- 数据请求:
Umi-hook/useRequest + axios
- 规范检测:
Eslint + prettier + husky + lint-staged + commitlint
代码规范化提交
husky
注册 git 的钩子函数保证在 git 执行 commit 时调用代码扫描的动作lint-staged
保证只对当前 add 到 stage 区的文件进行扫描prettier
自动格式化代码eslint
按照配置扫描代码@commitlint/cli
规范 commit 提交@commitlint/config-conventional
commtlint 通用配置
工作流
- 待提交的代码
git add
添加到暂存区 - 执行
git commit
husky
注册在git pre-commit
的钩子函数被调用,执行lint-staged
lint-staged
取得所有被提交的文件依次执行写好的任务(ESLint 和 Prettier)- 如果有错误(没通过ESlint检查)则停止任务,同时打印错误信息,等待修复后再执行
git commit
- 成功 commit,可 push 到远程
package.json配置如下:
{
...
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
},
"lint-staged": {
"src/**/*.{jsx,js,tsx,ts}": [
"prettier --write",
"eslint --fix",
"git add"
]
}
}
.prettierrc.js
module.exports = {
"printWidth": 100, // 一行的字符数,如果超过会进行换行,默认为80
"tabWidth": 4,
"useTabs": false, // 注意:makefile文件必须使用tab
"singleQuote": true,
"semi": true,
"trailingComma": "es5", //是否使用尾逗号,有三个可选值"<none|es5|all>"
"bracketSpacing": true, //对象大括号之间是否有空格,默认为true,效果:{ foo: bar }
"endOfLine": "auto",
"arrowParens": "avoid"
};
.eslintrc.js
module.exports = {
"root": true,
"env": {
"browser": true,
"node": true,
"es6": true,
"jest": true,
"jsx-control-statements/jsx-control-statements": true
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"sourceType": 'module',
"ecmaFeatures": {
"jsx": true,
"experimentalObjectRestSpread": true
}
},
"globals": {
// "wx": "readonly",
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:jsx-control-statements/recommended", // 需要另外配合babel插件使用
"prettier"
],
"overrides": [
{
"files": ["**/*.tsx"],
"rules": {
"react/prop-types": "off"
}
}
],
"settings": {
"react": {
"version": "detect"
}
},
"plugins": ["@typescript-eslint", "react", "react-hooks", "jsx-control-statements", "prettier"],
"rules": {
"prettier/prettier": 1,
"no-extra-semi": 2, // 禁止不必要的分号
"quotes": ['error', 'single'], // 强制使用单引号
"no-unused-vars": 0, // 不允许未定义的变量
"jsx-control-statements/jsx-use-if-tag": 0,
"react-hooks/rules-of-hooks": "error", // 检查 Hook 的规则
"react-hooks/exhaustive-deps": "warn" // 检查 effect 的依赖
}
};
.eslintignore/.prettierignore
**/*.js
!src/**/*.js
.commitlintrc.js
module.exports = {
extends: ['@commitlint/config-conventional']
};
提交需遵循 conventional commit 格式,即:
type(scope?): subject
e.g. feat: 教培PC框架搭建(cvi-3000)
type 可以是:
feat
:新功能(feature)upd
:更新某功能fix
:修补bugdocs
:文档(documentation)style
: 格式(不影响代码运行的变动)refactor
:重构(即不是新增功能,也不是修改bug的代码变动)test
:增加测试chore
:构建过程或辅助工具的变动
样式方案
styled-components