yx_generate_api_js/README.md

13 KiB
Raw Blame History

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.mjs
  • run-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

这条命令会:

  1. 拉取 swaggerUrl
  2. outputDir 下生成 API 文件
  3. 生成 outputDir/index.js
  4. 把导出同步到 externalIndexFile

一个完整的日常流程

第一次接入时:

npx yx-generate-api init
npx yx-generate-api gen

后端接口更新后,通常只需要再执行一次:

npx yx-generate-api gen

如果你只是想重新整理外部入口文件,而不重新拉 Swagger

npx yx-generate-api sync

配置说明

所有写在配置文件里的路径,默认都相对于配置文件所在目录,而不是命令执行目录。

顶层配置

  • swaggerUrl Swagger/OpenAPI JSON 来源。支持 http(s)file://、本地 JSON 文件路径。生成时必填。
  • swaggerTimeoutMs 拉取远程 Swagger 的超时时间,单位毫秒,默认 20000
  • outputDir 生成目录。默认是 src/api/generated
  • externalIndexFile 业务侧统一导出文件,例如 src/api/index.js。如果不填,默认不会执行同步。
  • requestImport 生成模块里 import request from '...' 的路径。它应该相对于每个生成出来的模块文件。
  • paramStyle 函数参数风格,可选 objectpositional,默认 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 '...' 的路径。不填时会自动根据 externalIndexFileoutputDir 计算。

命令详解

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

匹配时会忽略大小写和大部分分隔符,所以下面这些通常都能匹配到同一个模块:

  • Curriculum
  • curriculum
  • class-assignment
  • classAssignment

模块名是怎么推导的

生成器会优先从接口路径推导模块名:

  • /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 提供 buildUrlstringifyParams 等公共方法,不再依赖额外的 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

它支持两种使用方式:

  • 直接双击运行 会先提示你输入模块名或额外参数;留空则执行全量生成。
  • 在命令行里带参数运行 会直接把参数透传给 yx-generate-api gen

它内部的核心行为相当于:

npx yx-generate-api gen %*

双击时可输入的内容示例:

Curriculum
Ranking EnglishWord
--modules=Ranking,EnglishWord

适合给不常开命令行的同事直接双击执行,也保留了命令行传参的灵活性。

也可以在命令行里继续传参:

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