前端基建落地
00 分钟
2023-1-4
2023-9-11
type
status
date
slug
summary
tags
category
icon
password

一. 项目目录规范

文件目录组织现在常用的有两种方式,后面公司采用的第二种,更方便一些。两种方式没有最好的,只有更适合自己公司的,只要公司内部达成一致了,用哪一种都会很方便。
1.1 按功能类型来划分
按文件的功能类型来分,比如api组件页面路由hooksstore,不管是全局使用到的,还是单独页面局部使用到的,都按照功能类型放在src下面对应的目录里面统一管理。
1.2 按领域模型划分
按照页面功能划分,全局会用到的组件api等还是放到src下面全局管理,页面内部单独使用的api组件放到对应页面的文件夹里面,使用的时候不用上下查找文件,在当前页面文件夹下就能找到,比较方便,功能也内聚一些。

二. 代码书写规范

规范比较多,这里只简单列举一下基本的规范约束和使用工具来自动化规范代码。
2.1 组件结构
react组件
ITitlePropsI为开头代表类型,中间为语义化Title,后面Props为类型,代表是组件参数。
2.2 定义接口
例1: 登录接口,定义好参数类型和响应数据类型,参数类型直接定义params的类型,响应数据放在范型里面,需要在封装的时候就处理好这个范型。
2.3 事件
on开头代表事件,这个只是规范,on要比handle短一点,哈哈。
2.4 工具约束代码规范
除了约定俗称的规范,我们也需要借助一些工具和插件来协助我们更好的完成规范这件事情。
代码规范
  1. vscode:统一前端编辑器。
  1. editorconfig: 统一团队vscode编辑器默认配置。
  1. prettier: 保存文件自动格式化代码。
  1. eslint: 检测代码语法规范和错误。
  1. stylelint: 检测和格式化样式文件语法
git提交规范
  1. husky:可以监听githooks执行,在对应hook执行阶段做一些处理的操作。
  1. lint-staged: 只检测暂存区文件代码,优化eslint检测速度。
  1. pre-commitgithooks之一, 在commit提交前使用tsceslint对语法进行检测。
  1. commit-msggithooks之一,在commit提交前对commit备注信息进行检测。
  1. commitlint:在githookspre-commit阶段对commit备注信息进行检测。
  1. commitizengit的规范化提交工具,辅助填写commit信息。

三. 状态管理器优化和统一

3.1 优化状态管理

reactcontext封装了一个简单的状态管理器,有完整的类型提升,支持在组件内和外部使用,也发布到npm

3.2 store目录结构

3.3 定义状态管理器

1. 在store/index.ts中引入
2. 在顶层通过StoreProvider注入状态

3.4 使用状态管理器

1. 在函数组件中使用,借助useModel
2. 在class组件中使用,借助connectModel
3. 在组件外使用, 借助getModel
也可以在组件内读取修改状态方法,不回引起更新

四. 本地存储统一管理

可以对localStoragesessionStorage还有cookie简单封装一下,封装后使用的好处:
  1. 自动序列化,存储的时候转字符串,取得时候再转回来。
  1. 类型自动推断,在实例化的时候传入类型,在设置和获取值的时候都会自动类型推断。
  1. 可以统一管理,把本地存储都放在一个文件里面,避免后期本地存储混乱不好维护问题。
  1. 抹平平台差异,这个思路web,小程序,移动端,桌面端都适合。
实例化封装的本地存储
页面内使用

五. 封装请求统一和项目解耦

5.1 现有的封装
项目现用的请求封装和项目业务逻辑耦合在一块,不方便直接复用,使用上比较麻烦,每次需要传GETPOST类型,GET参数要每次单独做处理,参数类型限制弱。
5.2 推荐使用
推荐直接使用fetch封装或axios,项目中基于次做二次封装,只关注和项目有关的逻辑,不关注请求的实现逻辑。在请求异常的时候不返回Promise.reject(),而是返回一个对象,只是code改为异常状态的code,这样在页面中使用时,不用用try/catch包裹,只用if判断code是否正确就可以。
5.3 使用
使用上面代码命名定义接口类型的loginApi例子

六. api接口管理统一

文件夹路径
定义类型
定义请求接口
使用请求接口
使用上面代码命名定义接口类型的loginApi例子

七. 函数库-通用方法抽离复用

把公司项目中常用的方法hooks抽离出来组成函数库,方便在各个项目中使用,通过编写函数方法,写jest单元测试,也可以提升组内成员的整体水平。当时组内前端不管是实习生还是正式成员都在参与函数库的建设,很多就有了 30+ 的函数和hooks,还在不断的增加。
是用了dumi2来开发的函数库,可以看我的这篇文章【前端工程化】使用dumi2搭建React组件库和函数库详细教程

八. 组件库-通用组件抽离复用

公司项目多了会有很多公共的组件,可以抽离出来,方便其他项目复用,一般可以分为以下几种组件:
  1. UI组件
  1. 业务组件
  1. 功能组件:上拉刷新,滚动到底部加载更多,虚拟滚动,拖拽排序,图片懒加载..
由于公司技术栈主要是react,组件库也是采用了dumi2的方案,可以看我的这篇文章【前端工程化】使用dumi2搭建React组件库和函数库详细教程

九. css超集和css模块化方案统一

css超集
使用less或者scss,看项目具体情况,能全项目统一就统一。
css模块化
vue使用自带的style scoped, react使用css-module方案。
开启也简单,以vite为例,默认支持,可以修改vite.config.ts配置:
使用的时候,样式文件命名后缀需要加上 .module,例如index.module.less
组件里面使用:
编译后类名会变成title-[hash:5],可以有效避免样式冲突,减少起类名的痛苦。

十. 引入immer来优化性能和简化写法

Immermobx 的作者写的一个 immutable 库,核心实现是利用 ES6Proxy(不支持Proxy的环境会自动使用Object.defineProperty来实现),几乎以最小的成本实现了 js 的不可变数据结构,简单易用、体量小巧、设计巧妙,满足了我们对js不可变数据结构的需求。
1. 优化性能
修改用户信息
上面某次修改age没有变,但setUserInfo时每次都生成了一个新对象,更新前后引用变化了,组件就会刷新。
使用immer后,age没变时不会生成新的引用,同时语法也更简洁,可以优化性能。
2.简化写法
react遵循不可变数据流的理念,每次修改状态都要新生成一个引用,不能在原先的引用上进行修改,所以在对引用类型对象或者数组做操作时,总要浅拷贝一下,再来做处理,当修改的状态层级比较深的时候,写法会更复杂。
以数组为例,修改购物车某个商品的数量:
3. 可以用use-immer简化写法:

十一. 搭建npm私服

公司前端项目不推荐使用太多第三方包,可以自己搭建公司npm私服,来托管公司自己封装的状态管理库,请求库,组件库,以及脚手架clisdknpm包,方便复用和管理。
可以看我这两篇文章,都可以搭建npm私服:

十二. 各类型项目通用模版封装

可以提前根据公司的业务需求,封装出各个端对应通用开发模版,封装好项目目录结构,接口请求,状态管理,代码规范,git规范钩子,页面适配,权限,本地存储管理等等,来减少开发新项目时前期准备工作时间,也能更好的统一公司整体的代码规范。
  1. 通用后台管理系统基础模版封装
  1. 通用小程序基础模版封装
  1. 通用h5端基础模版封装
  1. 通用node端基础模版封装
  1. 其他类型的项目默认模版封装,减少重复工作。

十三. 搭建cli脚手架下载模版。

搭建类似vue-cli, vite, create-react-app类的cli命令行脚手架来快速选择和下载封装好的模版,比git拉代码要方便。

十四. git操作规范

git操作规范也很重要,流程不规范很容易出现比较复杂的问题,要根据公司现有情况和业界比较好的实践方案制定一套适合自己公司的git flow开发规范,用各种限制方案来避免出现问题,这个具体流规范后面会总结一篇文章出来。

十五. 规范和使用文档输出文档站点

代码规范和git提交规范以及各个封装的库使用说明要输出成文档部署到线上,方便新同事快速熟悉和使用。
这个是很重要的,做了再多的基建和规范,如果没有一个公共的文文档来查阅,就没办法快速熟悉,所以要一个线上的规范文档,把所有的规范都写进去,可以用语雀