1.引言
开发中,我们是否经常遇到以下痛点:
- 项目越大,启动和热更新越来越慢,启动都要花个3-5分钟以上
- 没有类型,接口返回的Object不拿到真实数据都不知道有哪些字段
- 需要手动写很多request函数去调用api,手动书写各种判断枚举值
- 缺乏代码格式化,代码错误检查,git commit规范
- 难以维护的css代码和文件,js里面书写编写css时没有提示,js里面无法使用css高级用法
- 数据流要么太死板,对ts支持很差(dva),要么太灵活(mobx)
- 重度依赖redux,需要写很多模板文件
- npm包管理问题,比如:多版本的npm包冲突、npm包依赖嵌套、npm僵尸包、npm依赖包平铺到nodule_modules首层
- 手动变更接口的loading状态、手动管理modal的visible状态
- 页面经常因为js错误导致白屏,体验很差
基于以上痛点,菜鸡的我整合了一些开源技术搭了一套脚手架供自己使用,并分享给大家学习,如果对你有帮助请在github上面给我一个star🙏🙏🙏
2.脚手架核心技术
- 打包编译 - vite
- 包管理 - pnpm
- 编程语言 - typescript
- 前端框架 - react
- 路由 - react-router
- UI组件库 - antd
- cssinjs(不考虑性能开销) - emotion
- 全局数据共享 - zustand
- 自动生成api - openapi
- 网络请求 - axios
- 数据请求利器 - react-query
- 通用hook(可不用) - ahooks
- 错误边界 - react-error-boundary
- 前端日志(暂未集成) - sentry-javascript
- hack - babel
- 代码检查 - eslint
- ts代码检查插件 - typescript-eslint
- 代码美化 - prettier
- git钩子 - husky
- commit格式化 -commitlint
2.自动基于后端swagger文件生成request函数
js
// src/core/openapi/index.ts
// 示例代码
generateService({
// openapi地址
schemaPath: `${appConfig.baseURL}/${urlPath}`,
// 文件生成目录
serversPath: "./src",
// 自定义网络请求函数路径
requestImportStatement: `/// <reference types="./typings.d.ts" />\nimport request from "@request"`,
// 代码组织命名空间, 例如:Api
namespace: "Api",
});
3.调用接口示例
js
// HelloGet是一个基于axios的promise请求(自动生成)
export async function HelloGet(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: Api.HelloGetParams,
options?: { [key: string]: any },
) {
return request<Api.HelloResp>('/gin-demo-server/api/v1/hello', {
method: 'GET',
params: {
...params,
},
...(options || {}),
});
}
// 自动调用接口获取数据
const { data, isLoading } = useQuery({
queryKey: ["hello", name],
queryFn: () => {
return HelloGet({ name: name });
},
});
// HelloPost是一个基于axios的promise请求(自动生成)
export async function HelloPost(body: Api.HelloPostParam, options?: { [key: string]: any }) {
return request<Api.HelloResp>('/gin-demo-server/api/v1/hello', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
// 提交编辑数据
const { mutate, isLoading } = useMutation({
mutationFn: HelloPost,
onSuccess(data) {
setName(data?.data || "");
},
onError() {
// 清除queryKey为hello的接口数据缓存,自动重新获取接口数据
queryClient.invalidateQueries({ queryKey: ['hello'] });
}
})
mutate({ name: "lisi" });
4.技术说明
- UI组件库(ant-design): 开箱即用,省心省力。没有选择headless-ui,还没有看到成熟的方案(chakra-ui使用成本也很高),封装成本高,会一直持续关注
- 通用hook(ahooks): 一个hook工具库,没有什么特别的亮点,就是hook增强,该库可以依据个人喜好选择是否使用
- 路由(react-router-dom): 自身默认支持错误边界功能,我觉得react-error-boundary更好用点,所以用hack绕过了react-router-dom的错误边界(ps: 暂时不支持参数禁用错误边界),react-router-dom官方没有提供prop禁用默认的错误边界
- 前端日志(sentry): 暂时未集成,需要进一步调研实用性和可用性
- 自动生成request函数(openapi): 后端接入apenapi后,前端可以根据openapi文件自动生成request api,通常使用基于openapi规范的swagger