13 KiB
yx-generate-api
yx-generate-api 是一个面向前端项目的 Node CLI,用来从 Swagger/OpenAPI JSON 生成 API 文件,并把生成目录的导出同步到你项目里的统一入口文件。
它主要解决两件事:
- 根据接口文档自动生成
generated/*.js - 自动维护业务侧
index.js里的导出区块,避免手写和漏改
先理解这 4 个命令
如果你先记住这四个命令,基本就会用了:
init在当前目录生成模板配置文件和 Windows 启动脚本。generate只生成 API 文件,不改外部入口文件。sync只同步外部index.js的受管导出区块。gen先执行generate,再执行sync。日常最常用。
环境要求
- Node
^20.19.0 || >=22.12.0 - 业务项目里要有一个默认导出的
request模块,生成代码会按requestImport指向它 - Swagger 源可以是
http(s)地址、file://URL,或者本地 JSON 文件路径
安装
在业务项目中直接安装:
npm install -D git+https://gitea.23544.com/wangyang/yx_generate_api_js.git
安装完成后,通常通过 npx yx-generate-api ... 调用。
快速开始
1. 生成模板文件
在业务项目根目录执行:
npx yx-generate-api init
会创建两个文件:
yx-generate-api.config.mjsrun-yx-generate-api.bat
其中 yx-generate-api.config.mjs 现在默认自带字段注释,方便首次接入时直接按提示修改。
如果文件已存在,使用 --force 覆盖:
npx yx-generate-api init --force
2. 修改配置
下面是一个和 init 模板一致的带注释示例:
export default {
// Swagger/OpenAPI 来源。
// 支持 http(s)、file://,也支持本地 JSON 文件路径。
swaggerUrl: 'http://127.0.0.1:8080/swagger/v1/swagger.json',
// 远程 Swagger 加载超时时间,单位毫秒。
swaggerTimeoutMs: 20000,
// 生成文件输出目录。
// 相对路径会基于当前配置文件所在目录解析。
outputDir: 'src/api/aixue/generated',
// 由 `sync` / `gen` 维护的外部 API 入口文件。
externalIndexFile: 'src/api/aixue/index.js',
// 写入到生成模块中的 request 导入路径。
// 这个路径必须相对于每个生成后的模块文件来写。
requestImport: '../request',
// 生成函数的参数风格,可选 'object' 或 'positional'。
paramStyle: 'object',
// 全量生成时,是否清理已经过期的自动生成模块文件。
// 如果是部分模块生成,会自动跳过清理,避免误删其他模块。
cleanOutput: true,
sync: {
// 如果你只想生成文件、不想改 externalIndexFile,可以设为 false。
enabled: true,
// 是否在受管区块中附带 generated/index.js 的注释快照。
includeGeneratedIndexSnapshot: true,
// externalIndexFile 里受管区块的开始和结束标记。
blockStart: '// AUTO-GENERATED API EXPORTS START',
blockEnd: '// AUTO-GENERATED API EXPORTS END',
// 可选:
// snapshotTitle: '// generated/index.js content:',
// exportFrom: './generated',
},
}
3. 执行生成
npx yx-generate-api gen
这条命令会:
- 拉取
swaggerUrl - 在
outputDir下生成 API 文件 - 生成
outputDir/index.js - 把导出同步到
externalIndexFile
一个完整的日常流程
第一次接入时:
npx yx-generate-api init
npx yx-generate-api gen
后端接口更新后,通常只需要再执行一次:
npx yx-generate-api gen
如果你只是想重新整理外部入口文件,而不重新拉 Swagger:
npx yx-generate-api sync
配置说明
所有写在配置文件里的路径,默认都相对于配置文件所在目录,而不是命令执行目录。
顶层配置
swaggerUrlSwagger/OpenAPI JSON 来源。支持http(s)、file://、本地 JSON 文件路径。生成时必填。swaggerTimeoutMs拉取远程 Swagger 的超时时间,单位毫秒,默认20000。outputDir生成目录。默认是src/api/generated。externalIndexFile业务侧统一导出文件,例如src/api/index.js。如果不填,默认不会执行同步。requestImport生成模块里import request from '...'的路径。它应该相对于每个生成出来的模块文件。paramStyle函数参数风格,可选object或positional,默认object。cleanOutput是否在“全量生成”时清理当前输出目录里已经过期的自动生成模块文件。默认true。sync控制sync/gen如何维护外部入口文件。
sync 配置
sync.enabled是否启用同步。默认值等于Boolean(externalIndexFile)。sync.blockStart受管区块开始标记。sync.blockEnd受管区块结束标记。sync.includeGeneratedIndexSnapshot是否把generated/index.js的内容以注释形式写进受管区块。默认true。sync.snapshotTitle快照标题。默认是// generated/index.js content:。sync.exportFrom自定义export * from '...'的路径。不填时会自动根据externalIndexFile和outputDir计算。
命令详解
init
用途:在当前目录创建模板配置文件和 Windows 启动脚本。
npx yx-generate-api init
npx yx-generate-api init --force
generate
用途:只生成 API 文件,不同步外部入口。
npx yx-generate-api generate
常用写法:
npx yx-generate-api generate Curriculum
npx yx-generate-api generate class-assignment Ranking
npx yx-generate-api generate --modules=Curriculum,class-assignment
npx yx-generate-api generate --config ./yx-generate-api.config.mjs
npx yx-generate-api generate --url=http://127.0.0.1:8080/swagger/v1/swagger.json
npx yx-generate-api generate --url ./swagger/swagger.json
npx yx-generate-api generate --outDir=src/api/tmp-generated
npx yx-generate-api generate --requestImport=../request
npx yx-generate-api generate --timeout 10000
npx yx-generate-api generate --no-clean
npx yx-generate-api generate --paramStyle=positional
支持的参数:
--config=...指定配置文件路径。--url=...临时覆盖swaggerUrl。--timeout=...临时覆盖 Swagger 拉取超时,单位毫秒。--outDir=...临时覆盖输出目录。--requestImport=...临时覆盖生成文件里的 request 导入路径。--modules=...逗号分隔的模块列表。--clean全量生成时清理过期的自动生成模块文件。--no-clean保留已有生成模块文件。--paramStyle=object|positional临时覆盖参数风格。
命令行参数既支持 --key=value,也支持 --key value。
sync
用途:只同步外部入口文件。
npx yx-generate-api sync
npx yx-generate-api sync --config=./yx-generate-api.config.mjs
如果 sync.enabled=false,命令会直接跳过。
gen
用途:先 generate,再 sync。这是推荐的日常命令。
npx yx-generate-api gen
npx yx-generate-api gen Curriculum
npx yx-generate-api gen --modules=Curriculum,class-assignment
gen 接受和 generate 相同的运行时参数,例如 --config、--url、--timeout、--outDir、--requestImport、--paramStyle、--modules、--clean。
模块筛选规则
如果不传模块名,会生成 Swagger 里的全部模块。
如果传了模块名,只会生成匹配到的模块,例如:
npx yx-generate-api generate Curriculum
npx yx-generate-api generate class-assignment Ranking
npx yx-generate-api generate --modules=Curriculum,class-assignment
模块匹配时会同时参考这些值:
- 推导出的模块名
- 模块文件名的 kebab-case 形式
- Swagger operation 的
tags
匹配时会忽略大小写和大部分分隔符,所以下面这些通常都能匹配到同一个模块:
Curriculumcurriculumclass-assignmentclassAssignment
模块名是怎么推导的
生成器会优先从接口路径推导模块名:
/api/v1/Curriculum/list->Curriculum/api/Curriculum/list->Curriculum- 其他路径会优先使用第一个路径段
- 如果路径不合适,会退回到 Swagger
tags[0]
生成结果长什么样
假设配置如下:
export default {
outputDir: 'src/api/aixue/generated',
externalIndexFile: 'src/api/aixue/index.js',
requestImport: '../request',
}
执行 npx yx-generate-api gen 后,通常会得到这样的结构:
src/api/aixue/
index.js
request.js
generated/
shared.js
curriculum.js
class-assignment.js
index.js
其中:
shared.js提供buildUrl、stringifyParams等公共方法,不再依赖额外的qs包。curriculum.js某个模块的 API 方法集合。generated/index.js汇总导出每个模块,同时提供“命名空间导出”和“直接函数导出”。src/api/aixue/index.js业务侧入口文件,sync会在里面维护一个受管区块。
generated/index.js 的内容类似这样:
export * as classAssignmentApi from './class-assignment'
export * as curriculumApi from './curriculum'
export { getClassAssignmentListApi } from './class-assignment'
export { getCurriculumListApi } from './curriculum'
如果不同模块里恰好生成了同名函数,generated/index.js 会自动为冲突项补上模块前缀别名,避免导出冲突。
参数风格
paramStyle 决定生成函数的签名长什么样。
object
默认值。路径参数和查询参数统一放到 params,请求体放到 data。
const detailApi = (params = {}) => request.get(buildUrl(`/api/v1/course/{id}`, params))
const createApi = (params = {}, data) => request.post(buildUrl(`/api/v1/course/{id}`, params), data)
适合大多数前端项目,调用时更稳定,也更适合参数经常变动的接口。
positional
路径参数和查询参数会展开成位置参数,请求体仍然放最后一个 data。
const detailApi = (id, tab) => request.get(buildUrl(`/api/v1/course/{id}`, { id, tab }))
const createApi = (id, data) => request.post(buildUrl(`/api/v1/course/{id}`, { id }), data)
适合你明确想要“函数参数看起来更直接”的场景。
sync 会怎么改外部入口文件
sync 不会粗暴覆盖整个 externalIndexFile,它只维护一段带开始和结束标记的受管区块。
默认写进去的内容类似这样:
// AUTO-GENERATED API EXPORTS START
// Synced from 'src/api/aixue/generated/index.js'. Do not edit manually.
// generated/index.js content:
// export * as curriculumApi from './curriculum'
// export * as rankingApi from './ranking'
export * from './generated'
// AUTO-GENERATED API EXPORTS END
规则是:
- 如果外部文件里已经有这段标记,
sync会替换这段区块 - 如果还没有,
sync会把区块追加到文件末尾 - 标记外的内容会保留
如果你不想把 generated/index.js 的快照写进注释,可以把:
sync: {
includeGeneratedIndexSnapshot: false,
}
Windows 双击运行
init 会同时创建 run-yx-generate-api.bat。它会先切到脚本所在目录,再执行:
npx yx-generate-api gen %*
适合给不常开命令行的同事直接双击执行。
也可以在命令行里继续传参:
run-yx-generate-api.bat Curriculum
run-yx-generate-api.bat --modules=Curriculum,class-assignment
常见问题
1. 为什么 gen 没有同步外部 index.js
通常是下面几种情况:
- 没有配置
externalIndexFile sync.enabled=false- 你执行的是
generate,不是gen
2. 为什么生成文件里的 request 路径不对
requestImport 会原样写进生成文件,所以它必须相对于生成后的模块文件来写,而不是相对于 externalIndexFile。
例如生成目录是 src/api/aixue/generated,请求封装在 src/api/aixue/request.js,那么应该写:
requestImport: '../request'
3. 为什么命令行传的 --outDir 看起来和配置文件规则不一样
配置文件里的路径相对于“配置文件所在目录”。
命令行传入的 --config、--outDir,相对于“当前执行命令的目录”。
4. 为什么提示模块找不到
说明你传入的模块名没有匹配到任何已解析模块。可以先不带模块参数跑一次全量生成,观察生成出来的模块文件名,再按那个名字筛选。
5. 为什么有些旧模块文件没有被删掉
只有“全量生成”时,cleanOutput=true 才会清理过期的自动生成模块文件。
如果你这次是只生成部分模块,例如:
npx yx-generate-api generate Curriculum
工具会保留其他已有模块,避免误删。
本地开发
在工具仓库里直接查看帮助:
node ./bin/yx-generate-api.js --help
node ./bin/yx-generate-api.js generate --help
node ./bin/yx-generate-api.js sync --help