@umijs/openapi方式
依赖安装:
npm i @umijs/openapi ts-node -D
npm i umi-request
openapi配置:
在项目根目录新建 openapi.config.js
添加以下内容
const { generateService } = require('@umijs/openapi')
generateService({
schemaPath: 'http://xxx.com/springdoc/api-docs', // 可以是.json文件,也可以是远程json地址
serversPath: './src/servers',
})
vite配置:
export default defineConfig({
server: {
proxy: {
'^/api/': {
target: 'http://xxx.com',
changeOrigin: true
},
}
},
}
package脚本配置:
{
"scripts": {
"openapi": "ts-node openapi.config.ts"
}
}
运行命令生成文件:
npm run openapi
因为 tsconfig.app.json
已经包含了 src
目录下的所有文件,所以不用再到 env.d.ts
中添加引用 /// <reference types="./src/servers/api/typings" />
了。
生成的接口文件修改:
因为生成的接口文档是通过 umi
导入的 request
,但在 vite + typescript
环境中会提示 request
不在 umi
的导出模块里,所以这块需要修改掉,单独使用 umi-request
来处理接口请求,umi-request
结合了 fetch
和 axios
的特性进行封装,文件小且使用方便。
把
import { request } from 'umi'
修改成
import request from 'umi-request'
批量替换,在项目根目录新建一个 openapi.replace.bat
文件,内容如下:
@echo off
chcp 65001 > nul
setlocal enabledelayedexpansion
set "old_text=import { request } from 'umi';"
set "new_text=import request from 'umi-request';"
set "file_pattern=src/servers/api/*.ts"
for %%f in (%file_pattern%) do (
set "old_file=%%~nf%%~xf"
set "new_file=%%~nf_output%%~xf"
set "input_file=src/servers/api/%%~nf%%~xf"
set "output_file=src/servers/api/%%~nf_output%%~xf"
(for /f "usebackq delims=" %%a in (!input_file!) do (
set "line=%%a"
set "line=!line:%old_text%=%new_text%!"
echo(!line!
)) > !output_file!
(for /f "usebackq delims=" %%a in (!output_file!) do (
set "line=%%a"
set "line=!line!"
echo(!line!
)) > !input_file!
del "%cd%\src\servers\api\%%~nf_output%%~xf"
)
修改 package.json
{
"scripts": {
"openapi-create": "ts-node openapi.config.ts",
"openapi-replace": "openapi.replace.bat",
"openapi": "npm run openapi-create && npm run openapi-replace"
}
}
运行命令
npm run openapi
页面中使用:
import { getUserList } from '@/servers/api/xxx'
getUserList()
swagger-typescript-api方式
依赖安装:
npm i vite swagger-typescript-api vite-plugin-swagger-typescript-api -D
npm i axios
vite配置:
vite.config.js
// 在 vite.config.ts 文件中添加如下配置
import { defineConfig } from 'vite'
import { vitePluginSwaggerTypescriptApi } from 'vite-plugin-swagger-typescript-api'
// vite 相关配置请参考 https://vitejs.dev/config/
export default defineConfig({
server: {
proxy: {
'^/api/': {
target: 'http://xxx.com',
changeOrigin: true
},
}
},
plugins: [
vitePluginSwaggerTypescriptApi({ // swagger-typescript-api 的配置,具体可参考 https://github.com/acacode/swagger-typescript-api
name: 'index.ts', //要生成的文件名称
output: path.resolve('./src/api'), // 生成的文件所在的文件夹,注意要使用 path.resolve 解析出绝对路径,否则路径可能会有错误
input: path.resolve('./swagger.json'), // 从本地文件载入,路径问题同 output
url: "http://xxx.com/springdoc/api-docs", // 如果从远程接口载入,只要返回的是json数据,不一定非要.json结尾
httpClientType: 'axios', // or "fetch" 生成的接口类型
})
]
})
配置完后,每次执行 vite
命令或每次保存都会重新生成,如果不想一直重新生成,可以在生成一次后注释掉配置。
生成的接口文件修改:
把
import axios, {
AxiosInstance,
AxiosRequestConfig,
AxiosResponse,
HeadersDefaults,
ResponseType
} from 'axios'
修改成,不然会报错
import axios from 'axios'
import type {
AxiosInstance,
AxiosRequestConfig,
AxiosResponse,
HeadersDefaults,
ResponseType
} from 'axios'
然后把 baseURL
那一行注释掉
constructor({
securityWorker,
secure,
format,
...axiosConfig
}: ApiConfig<SecurityDataType> = {}) {
this.instance = axios.create({
...axiosConfig,
// baseURL: axiosConfig.baseURL || 'http://xxx/com'
})
this.secure = secure
this.format = format
this.securityWorker = securityWorker
}
页面中使用:
import { Api } from '@/api'
const { getUserList } = new Api().api
getUserList()
总结
两种方式都可以根据 openapi+swagger 生成的接口描述转换成前端可使用的接口方法,两种方式都需要对生成的接口文件进行修改,不同的是 @umijs/openapi
方式生成文件结构分层更清晰,而 swagger-typescript-api
则是把生成接口汇总到一个文件里,这样会使文件越来越大,而且需要先 new
一下才能使用,综合比较使用 @umijs/openapi
的方式可能更好,当然也要结合实际的项目需求来最终确定使用哪种方式。