vite-plugin-openapi-ts:让 Vite 项目消费 OpenAPI 更优雅
在很多前后端分离项目里,后端已经提供了比较完整的 OpenAPI(Swagger)文档,但前端依然需要:
- 手写一堆
axios/fetch封装; - 自己维护接口类型,接口一改就容易“代码没改全”;
- 在多个项目里重复造一遍轮子。
vite-plugin-openapi-ts 就是为这个场景准备的:
它是一个 Vite 插件,可以从 OpenAPI 规范自动生成 TypeScript 类型 和 类型安全的 API 客户端,同时还提供 CLI,方便集成到各种工作流里。
核心卖点一览
- ✨ 自动生成代码:从 OpenAPI 生成 TS 类型 + API 客户端
- 🔒 类型安全:请求参数、响应数据都有完整类型提示
- 🎯 框架无关:只要是 Vite 项目,都能用(Vue / React / Svelte / …)
- 📦 零配置起步:只需给一个 OpenAPI 地址即可跑起来
- 🔄 自动同步:构建时自动生成 / 更新类型
- 📄 多格式支持:JSON、YAML 都支持
- 🌐 OpenAPI 3.0 & 3.1:兼容主流版本规范
- 🛠 CLI 工具:支持命令行生成和清理缓存/生成文件
如果你正在用 Vite + TypeScript,并且有现成的 OpenAPI 文档,这个插件基本可以“零成本”提升你的开发体验和代码质量。
快速上手:三步搞定
1. 安装依赖
pnpm add -D vite-plugin-openapi-ts
# 或者
npm install -D vite-plugin-openapi-ts
yarn add -D vite-plugin-openapi-ts
2. 在 Vite 中注册插件
在 vite.config.ts 里加入:
import { defineConfig } from 'vite';
import openapiPlugin from 'vite-plugin-openapi-ts';
export default defineConfig({
plugins: [
openapiPlugin({
url: 'http://localhost:8080/v3/api-docs', // OpenAPI 文档地址
baseUrl: 'http://localhost:8080', // API 基础地址,可省略让插件自动推导
outputDir: 'src/openapi', // 生成代码输出目录,默认也是这个
})
]
});
支持 JSON 也支持 YAML:
openapiPlugin({
url: 'http://localhost:8080/swagger.yaml',
baseUrl: 'http://localhost:8080',
outputDir: 'src/openapi',
});
如果你本地已经有一个 OpenAPI 文件,也可以直接用“本地文件路径”作为输入,例如:
openapiPlugin({
// 直接指向本地 openapi.json / openapi.yaml
url: './openapi.yaml',
// 本地文件场景下,建议总是显式配置一个正确的 baseUrl
baseUrl: 'https://api.example.com',
outputDir: 'src/openapi',
});
此时插件会在构建/启动 Dev Server 时读取本地文件内容,并生成对应的类型和客户端代码。
构建或启动开发服务器时,插件会自动拉取 OpenAPI 规范,根据内容生成:
src/openapi/schemes.ts:所有 schema 对应的 TS 类型src/openapi/index.ts:带拦截器、错误封装的 API 客户端
3. 在代码中直接调用
import apiClient from '@/openapi'; // 对应 outputDir
// 路径参数 + 类型安全
const { data: user } = await apiClient(
'/users/{id}',
'get',
{
params: { id: '123' },
}
);
// 查询参数
const { data: users } = await apiClient(
'/users',
'get',
{
query: { page: 1, limit: 10 },
}
);
// 带请求体
const { data: newUser } = await apiClient(
'/users',
'post',
{
body: { name: 'Alice', email: 'alice@example.com' },
}
);
接口路径、方法名、参数结构、返回类型,都会有完整的 TypeScript 提示和校验。
高级特性:不仅仅是“生成类型”而已
1. 全局配置与基础设置
生成的客户端通常还会导出一个 config 对象,你可以统一设置:
import apiClient, { config } from '@/openapi';
config.baseUrl = 'https://api.example.com';
config.headers = {
'Content-Type': 'application/json',
Authorization: 'Bearer your-token',
};
const { data } = await apiClient('/users', 'get');
在团队项目里,可以在应用初始化阶段设置一次,全局生效。
2. 请求 / 响应拦截器
和你在 axios 里习惯的用法类似,生成的客户端也支持拦截器:
import apiClient, { interceptors } from '@/openapi';
// 请求拦截器:统一加 token、打日志等
const removeRequestInterceptor = interceptors.request.use(async (config) => {
config.headers['Authorization'] = `Bearer ${getToken()}`;
console.log('Request:', config.method, config.url.pathname);
return config;
});
// 响应拦截器:统一处理状态码
interceptors.response.use(async (response) => {
console.log('Response:', response.response.status);
return response;
});
// 错误拦截器:集中处理 401 / 500 等
interceptors.error.use(async (error) => {
if (error.status === 401) {
// 比如跳转登录
window.location.href = '/login';
}
throw error;
});
这让你可以在一个地方集中处理认证、日志上报、全局错误提示等逻辑。
3. 请求取消、超时与重试
- 支持通过
AbortController取消请求,非常适合 React / Vue 组件卸载时清理。 - 支持设置全局超时时间,避免某些接口“卡死”。
- 支持配置自动重试策略,对网络抖动比较友好。
这些能力在生成的客户端中已经帮你封装好,你只需要在需要的位置打开相关配置即可。
CLI 支持:适合 CI / 工具链集成
除了 Vite 插件,你还可以使用 CLI 命令:
npx openapi-ts generate --url http://localhost:8080/v3/api-docs --base-url http://localhost:8080
常见能力包括:
generate/gen:根据 OpenAPI 生成类型和客户端;clean:删除生成的schemes.ts和index.ts,可选是否清理缓存;clean-cache:单独清理.openapi-cache.json。
配合 CI 或 monorepo,你可以在构建前先跑一遍生成脚本,再让各个子应用消费统一生成的客户端。
生成策略与缓存机制
实际落地时,你通常不希望“每次构建都重新拉一次 OpenAPI 然后生成代码”,否则在 CI 或本地开发场景下会浪费不少时间。
为此,vite-plugin-openapi-ts 内部做了一个很轻量的缓存机制,大致规则是:
- 每次生成时,会计算 OpenAPI 文本内容的哈希(以及当前使用的
baseUrl); - 在输出目录下写入一个
.openapi-cache.json,记录本次的哈希值和时间戳; - 下次生成时,如果发现“哈希没变 + baseUrl 一致”,就直接跳过生成;
- 你也可以通过配置:
enableCache:关闭或开启缓存(默认开启);skipTimeout:设置“最近多久之内不要重复生成”(单位毫秒);force:强制重新生成,忽略缓存和skipTimeout。
简单理解就是:在接口文档没变的情况下,插件会尽量不打扰你,把生成这件事变成一次“几乎无感”的操作。
用 openapi.config.json 统一管理配置
为了方便在不同环境(本地 / CI / 多个子项目)之间共享配置,插件和 CLI 还支持从项目根目录下读取一个 openapi.config.json 文件:
- 当你在
vite.config.ts里调用openapiPlugin()、但不传入任何参数时,插件会尝试读取openapi.config.json中的配置; - 当你在命令行里执行
npx openapi-ts generate时,CLI 会把openapi.config.json作为默认值,再用命令行参数进行覆盖。
这个配置文件长得大概像这样:
{
"url": "http://localhost:8080/v3/api-docs",
"baseUrl": "http://localhost:8080",
"outputDir": "src/openapi",
"enableCache": true,
"skipTimeout": 0,
"force": false
}
一种比较推荐的使用方式是:
- 把团队约定好的默认配置都写在
openapi.config.json里(文档地址、基础 URL、输出目录、缓存策略等); - 开发和测试环境里,直接:
- Vite 里用
openapiPlugin()空参启动; - 命令行里用
npx openapi-ts generate;
- Vite 里用
- 如果某个环境需要临时覆盖配置(比如 CI 想连另一个环境的网关),就用命令行参数覆盖:
npx openapi-ts generate \
--url https://api-dev.example.com/openapi.json \
--base-url https://api-dev.example.com \
--force
这样,媒体文章的读者即使完全没看过 README,也可以直接照着这几段配置抄过去,在自己的项目里跑起来。
适用场景与团队收益
这里只列几个典型场景:
- 已经有比较规范的 Swagger / OpenAPI 文档,希望前端自动获得接口类型和客户端;
- 团队内部有多个前端项目,希望统一一套“接口 SDK”,减少重复封装;
- 希望在 PR / CI 阶段就能发现“接口字段改了,前端没改”的问题,而不是靠线上报错;
- 倾向用 TypeScript 做强类型约束,减少因
any带来的隐性 bug。
实战体验上,vite-plugin-openapi-ts 能明显减少手写接口层的工作量,同时提高接口变更的可见性和安全性,是非常典型的“提升团队长期生产力”的工具。
总结:为什么值得一试?
综合来看,这个项目有几个非常值得推荐的点:
- 聚焦 Vite + OpenAPI 这个高频组合,定位清晰;
- 功能覆盖到位,不只是“生成 d.ts”,而是“生成可用、可配置、可拦截的客户端”;
- 工程实现干净,缓存、日志、类型推导都考虑得比较细;
- 文档友好,中英文兼顾,对上手门槛要求不高。
需要特别说明的是:vite-plugin-openapi-ts 目前是我个人开发、在业余时间维护的开源项目,虽然在常见场景下已经可以正常使用,但我无法保证在所有 OpenAPI 规范、所有运行环境下都 100% 不出问题。建议大家优先在非生产环境或非关键资产项目里尝试使用,确认符合团队预期后,再逐步扩大使用范围。