README
彩票系前端工程V3.0开发指南
目标
前端项目日益增多,新平台开发已经成为前端工作的主要内容,V2版本的前端工程已经通过【配置偶合】+【视图分离】的方式对各平台差异化需求进行兼容 但随着项目爆发式增长,仍然产生很多无法避免的工作量,以及部分偶合公共组件带来的问题。 V3.0版本的前端工程着重关注以下问题:
- 多平台开发时,无法减少的开发工作量
- 偶合视图(共享组件)带来的平台相互影响可能
- 分散的目录结构导致多团队配合问题
- 集中式配置及依赖管理
- 多团队作协开发,技术差异导致代码质量各异
- 底层组件无类型校验和约束
技术栈
框架体系:
react - v1.16.12 / redux / typescript - v3.1
其他:
webpack / scss / lodash / axios
安装工程
npm start
启动工程
npm run build
工程编译
npm run build
跨域
默认开发时的API接口,由LS - domain改为:webpack - proxy
分支管理
与V2版本不同,V3版本 不再使用 master --> pc-master / h5-master 的方式进行管理
取而代之的是使用REACT HOOK代替 master
分支,使用 views/{platform}/{client}
来代替平台端
代码合并
由于不在使用逻辑/视图分支分离的方式,该项目OL之后合并master的工作交由测试处理,不再由前端处理
基本目录结构
web-main |- build |- src | |- assets | |- core (核心文件,影响全平台) | |-actions * redux行为 | |-constants * 常量 | |-middleware * redux中间件 | |-helpers * 工具类 | |-i18n * 国际化目录 | |-hooks * React HOOK - 提供视图层主体逻辑 | |-reducers * redux reducer | |-rules * 规则引擎 - 投注算法相关 | |-schemas * TS全局声明 | |-store * redux store | |-templates * 公共模板 | | | |- views (视图文件,影响单个项目或单个端) | |-xx(杏鑫工程) | |-assets * 静态资源 | |-i18n * 视图层国际化文件 | |-public * 公共配置 - 影响单个项目 | |-desktop * PC端视图 | |-mobile * H5端视图 : : :
配置管理
为了最大程度复用和分离平台与端的耦合,配置采用三层配置并使用继承与复写来
- 公共配置:
core/constants/configs
- 该配置影响全平台 - 项目配置:
views/{platform}/public/configs.ts
- 影响某平台(不分端),在此配置中引用公共配置,并向下导出 - 客户端配置:
views/{platform}/{client}/configs.ts
- 影响单平台单端,在此配置中引用项目配置
例:全平台公共配置 MANYCAI_STATISTICS,但其中A平台有URL差异,则在【项目配置】中进行变量复写
import CONFIG from '@constants/configs';
export const MANYCAI_STATISTICS = {
URL: 'http://others.com',
ALIAS: ['txffc', 'hn1fc', 'hn5fc', 'qqffc']
}
export default {
...CONFIG,
MANYCAI_STATISTICS
}
相同,如果只是客户端级别差异,则在【客户端配置】中进行复写
别名
对于不同工程的私有路径,如何在公共组件中进行区分,例如:
杏鑫平台配置文件路径:src/views/xx/desktop/config.ts
沐鸣平台配置文件路径:src/views/mm/desktop/config.ts
在公共组件中要使用对应的配置文件就需要用到别名进行处理
// webpack-z-load
const xx = {
client: client === 'pc' ? 'desktop' : 'mobile',
base: 'xx',
}
// webpack
const alias = {
'@this': path.join(__dirname, `../src/views/${CONFIG.base}/${CONFIG.client}`)
}
// component
import CONFIGS from '@this/config'
接口缓存
对于接口数据缓存,我们在V2的基础上添加了以下参数进行拓展:
/**
* 请求缓存相关
* @param expires 缓存时间 单位 分钟
* @param forward 当有缓存数据时,是否仍然请求去更新当前缓存
* @param clear 是否弃用当前缓存数据,重新缓存
*/
接口超时处理
不同于V2版本所有接口均30秒超时,且console.error抛错,V3版本对接口超时进行了完整的重写
/**
* 请求超时相关
* @param timeout 自定义超时时间 单位 s
* @param timeoutCb 自定义超时回调函数
* @param maxRetry 最大重试次数
*/
日志
通常对日志的管理分为以下3类
JS错误日志
在useLogs HOOK中,注册了全局异常捕获,所有发生在JS层的异常将被保存至 LocalStorge -> Exception 中三天
该错误日志将记录报错的JS行数列数,webpack打包之后需要使用source-location进行反向查找,具体使用方法参考github:https://github.com/front-end-yu/source-location
export default () => {
React.useEffect(() => {
window.addEventListener('error', function(e) {
errorHandler(e);
});
}, [])
}
网络慢日志
在useLogs HOOK中,使用networkHandler记录了请求大于5秒的慢日志三天,保存至 LocalStorge -> NetworkRecord
debug日志
在window对象下全局注册了debug日志对象devConsole代码及使用方法如下
interface IDevConsole{
key: string,
content: any
}
export const devConsole = {
log: ({key, content}: IDevConsole) => {
if((window as any).mode === 'debug' || localStorage.getItem('mode') === 'debug'){
console.log(`======${key}======`, content)
}
}
}
// 使用范例
devConsole.log({key: `push: ${res.module}`, content: res.data});
React HOOK
React hook作为本次重构的核心,在解耦合中起了重要的作用,已将在V2版本中的以下部分移植到HOOK中
- 所有HOC相关的操作
- 所有services的操作
- 不区分客户端的组件生命周期管理
- redux相关操作
HOC
由于React Hook的引入,大部分的HOC已经交由Hook托管,当前项目中只剩下权限相关的组件仍使用HOC进行处理
详细请到AuthOP/index.tsx查看
样式管理
目录
对于大多数【页面】/【组件】,在同一目录下都一一对应一个同名sass文件相依赖,例如:
- 首页
home/index.tsx
在其同一目录中home/home.scss
与之对应 - banner
template/desktop/components/banner/index.tsx
在其同一目录中/banner.scss
与之对应
模块化
为了避免相同className导致不同组件间样式冲突,每个组件或者页面都使用css模块化进行root节点类命名
:local(.wrapper){
}
import css from './home.scss';
return (
<div className={css.wrapper}>
</div>
)
FONT-ICON
为了在新项目生成过程中出现不必要的,因为ICON颜色引起的BUG,我们使用 @fontawesome 作为字体图标库
- @fortawesome/free-brands-svg-icons
- @fortawesome/free-regular-svg-icons
- @fortawesome/free-solid-svg-icons
若需要新图标,则在 https://fontawesome.com/icons 选区相关图标,再在对应的免费图标库中引入
不允许使用UI提供的普通图标,在FONT-ICON中找到相似的使用即可
图标相关的使用文档请参考: 官方文档 react-fortawesome
公共组件样式差异化
公共组件结构(功能)差异化
国际化
开发新平台步骤
- 以某工程为模板,复制 views/template 到 views 目录下
- 添加编译模板,在 webpack-z-load.js 中添加平台对应的相关参数
- 添加CLI模板,在cli/index.js 中添加 PLATFORM 以及平台对应语言和别名
- 修改当前项目,当前开发端的 veriables.scss 中主体色调
- 执行 npm run build 开始开发