yapi-to-typescript
yapi-to-typescript 是一个代码生成工具,其可根据 YApi 或 Swagger 的接口定义生成 TypeScript 或 JavaScript 的接口类型及其请求函数代码
安装
选择你常用的包管理器将 yapi-to-typescript 加入项目依赖即可:
# npm
npm i yapi-to-typescript
# yarn
yarn add yapi-to-typescript
# pnpm
pnpm add yapi-to-typescript
配置
首先, 在项目使用以下命令初始化配置文件:
npx ytt init
然后你的项目会生成一个 ytt.config.ts 或 ytt.config.js
以下是 ytt.config.ts 或 ytt.config.js 的配置
import { defineConfig } from 'yapi-to-typescript';
const tokenList = [
{
// 名称
name: 'name',
// 对应的token 获取方式:打开项目 -> 设置 -> token 配置 -> 复制 token
token: '',
categoryIds: [0],
}
]
// 项目中的能力可能不止一个, 所以得用循环去拿各个能力得配置
export default defineConfig(
tokenList.map((v) => ({
// 配置服务器地址
serverUrl: "https://yapi.xxxxxx.com", // 这里是你yapi的地址
// 是否只生成接口请求内容和返回内容的 TypeSript 类型,是则请求文件和请求函数都不会生成。
typesOnly: false,
// 要生成的目标代码类型
target: 'typescript',
// 支持生成 React Hooks 代码的相关配置。
reactHooks: {
// 是否开启该项功能。
enabled: false,
},
// 生产环境名称。用于获取生产环境域名。
prodEnvName: 'production',
// 输出文件路径。可以是 相对路径 或 绝对路径。如 'src/api/index.ts'
outputFilePath: `src/services/${v.name}Api.ts`,
// 请求函数文件路径。如 'src/api/request.ts'
// 这里默认不选会在 outputFilePath 输出的目录生成一个默认的request
requestFunctionFilePath: 'src/utils/request.ts', // 这里是改成用Axios配置的
// 接口返回的数据形
dataKey: 'data',
// 项目列表
projects: [
{
token: v.token,
categories: [
{
id: v.categoryIds,
getRequestFunctionName(interfaceInfo, changeCase) {
return changeCase.camelCase(interfaceInfo.method + interfaceInfo.path)
},
},
],
},
],
}))
)
使用
配置好上面后使用以下命令生成代码:
npx ytt
执行完成后就会在配置 outputFilePath 的目录下生成文件了, 例如上面我配置的是: src/services/${v.name}Api.ts 就会在 src 目录下的 services 文件夹生成对应的代码
使用 Axios 统一请求函数示例
下面是一个基于 Axios 的示例, 可通过配置项的 requestFunctionFilePath 将 request 指向你自己写的 request
# src/utils/request.ts
import Axios from "axios";
const basePrefix = '/api'
const BACK_GATEWAY = '/';
const defaultHeaders = {
'Content-Type': 'Application/json',
'token': '',
'environment': '1',
'source': '99',
site: 1
}
const request = Axios.create({
baseURL: BACK_GATEWAY,
timeout: 30 * 1000,
headers: defaultHeaders
})
// 添加请求拦截器
request.interceptors.request.use((config) => {
// 判断是否有权限
console.log("判断是否有权限: TOKEN")
// 在发送请求之前做些什么
return config
}, (error) => {
// 对请求错误做些什么
return Promise.reject(error)
});
// 添加响应拦截器
request.interceptors.response.use((response) => {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response
}, (error) => {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error)
});
export interface IRequestSuccess<T> {
code: number,
data: T,
message: string,
time: number
}
class ApiRequest {
// eslint-disable-next-line class-methods-use-this
createRequest<T>(options: any): Promise<unknown> {
return new Promise((resolve, reject) => {
request<IRequestSuccess<T>>({ url: basePrefix + options.path, ...options }).then(_reslove => {
const res = _reslove.data as IRequestSuccess<T>
// 登录验证
if (res.code === 1101) {
return false
}
// 统一拦截 参数校验错误,显示后端返回的状态信息
// @todo 这里不需要国际化
if (res.code === 1102) {
reject(res)
return false
}
// 请求成功执行
if (res.code === 1000) {
resolve(res)
} else {
resolve(res)
}
}).catch((err) => {
// http错误处理, 直接透传
reject(err)
})
})
}
}
export default new ApiRequest().createRequest;