likes
comments
collection
share

为了提效,手写脚手架根据yapi生成ts接口文件

作者站长头像
站长
· 阅读数 11

背景

前端项目使用的ts,但在对接后端生成的yapi文档时,只提供了数据结构,需要自己手动根据结构填写ts类型,接口目录中存在几十甚至上百个接口,手动填写会存在非常多无意义的机械运动。

yapi文档是后端同学部署,不方便直接去操作yapi项目,所以决定写一个无侵入式的接口生成脚手架工具。

于是花了几个小时的时间,结合自己的项目,完成了初版脚手架工具yapi-cli,在实现的这个过程中熟悉脚手架开发的流程,并且发布自己的npm包。

接下来会介绍脚手架的使用和开发的过程。

介绍与使用

脚手架功能很简单,就两个功能,一个初始化配置,一个创建。

安装

推荐全局安装

npm i -g yapi-ts-cli

查看帮助

执行yt -h就可以查看帮助信息。

yapi脚手架工具,帮助通过yapi创建ts和api文件

Options:
  -V, --version     output the version number
  -h, --help        display help for command

Commands:
  init              初始化配置
  create [options]  创建ts文件
  help [command]    display help for command

yt create相关命令可以一键创建全部的类型接口,也可以指定创建接口文件。

运行yt create -h可以查看create相关的帮助信息

创建ts文件

Options:
  -all, --all     下载该项目下所有接口
  -id, --id <id>  下载指定id接口
  -h, --help      display help for command

使用

首先初始化配置执行

yt init

修改配置信息

{
    path: "/src/api", // 保存目录
    cookie: "", // yapi的cookie
    url: "",  // 项目地址 例如:http://117.xx.xx.xx:3000
    projectId: "",  // 项目的id,例如:http://117.xx.xx.xx:3000/project/11/interface/api/43,这里的11就是项目id,填写11
    // headers: (info) => {},			// 特殊修改头部字符
  	// apiContent: (info) => {},	// 修改底部api接口字符
}

统一创建ts文件执行

yt create -all

只创建单个文件执行

yt create -id <id>

执行下载的得到的ts文件举例

import { post } from "@/utils/request";

export interface HardwareRebindCollectorReqQueryTypes {
  [k: string]: unknown;
}

export interface HardwareRebindCollectorReqTypes {
  /**
   * 设备型号
   */
  device_model?: string;
  /**
   * 设备地址 true
   */
  mac_arr?: string;
  /**
   * 设备所属网关ID
   * 如果设备是网关
   */
  wan_id?: string;
  [k: string]: unknown;
}

export interface HardwareRebindCollectorResTypes {
  /**
   * 信道
   */
  channel?: string;
  /**
   * 设备id
   */
  device_id?: string;
  /**
   * 网关ID
   */
  wan_id?: string;
  /**
   * 网关Lora地址
   */
  wan_lora_addr?: string;
  [k: string]: unknown;
}

/**
* 标题: 绑定采集器设备
* 描述: 绑定采集器设备
* 地址:http://11.xxx.xx.xxx:3000/project/11/interface/api/155
*/
export const hardwareRebindCollector = (data?: HardwareRebindCollectorReqTypes) =>
  post<HardwareRebindCollectorResTypes>("/api/hardware/rebind_collector", data);
  

脚手架开发

库介绍

功能相对比较简单,不是很复杂,脚手架所使用的常用库,这里先介绍一下几个库的作用

"commander": "^11.0.0",
"json-schema-to-typescript": "^13.1.1"

commander

提供了一种简洁且强大的方式来处理命令行参数、选项、子命令和帮助文档。使得创建复杂的 CLI 工具变得更加简单,能够轻松的实现脚手架中的命令行交互,在这个脚手架开发中,我仅使用了两个交互命令,createinit,在代码中是这样的:

program
  .name("yapi-cli")
  .description("yapi脚手架工具,帮助通过yapi创建ts和api文件")
  .version(packageJson.version);

// 配置初始化
program.command("init").description("初始化配置").action(init);

// 文件创建
program
  .command("create")
  .description("创建ts文件")
  .option("-all, --all", "下载该项目下所有接口")
  .option("-id, --id <id>", "下载指定id接口")
  .action(create);

program.parse();

通过commanderprogram方法,创建了两个简单的交互命令,command定义命令名,description进行描述,option定义选项和选项的值,随后就是去实现initcreate方法,当用户执行此子命令时,将调用 action 中的函数。

json-schema-to-typescript

要解决的核心问题是如何将yapi中的内容转换成ts文件,而yapi所存储实际上是一个JsonSchema数据,我们需要把一段json转换成ts类型,使用这个json-schema-to-typescript转换库,能够很方便的转换成ts类型,不用自己造轮子了。

让我们来看看yapi中的JsonSchema是什么样子的

{
	"type": "object",
	"properties": {
		"device_model": {
			"description": "设备型号",
			"type": "string"
		},
		"mac_arr": {
			"description": "设备地址 true",
			"type": "string"
		},
		"version": {
			"description": "设备版本",
			"type": "string"
		},
		"wan_id": {
			"description": "设备所属网关ID\n如果设备是网关",
			"type": "string",
			"example": "0"
		}
	},
	"$$ref": "#/definitions/vo.RebindCollectorReq"
}

而通过json-schema-to-typescript转换后得到ts数据,是不是很方便。

export interface HardwareRebindCollectorReqTypes {
  /**
   * 设备型号
   */
  device_model?: string;
  /**
   * 设备地址 true
   */
  mac_arr?: string;
  /**
   * 设备版本
   */
  version?: string;
  /**
   * 设备所属网关ID
   * 如果设备是网关
   */
  wan_id?: string;
  [k: string]: unknown;
}

init初始化实现

初始化只是将内置的配置文件copy了一份到执行目录,使用了fs-extra库中的copySync方法。

copySync(configPath, cwd + "/yapi-cli-config.mjs");

create实现

create中存在下载全部和下载单个ts文件,下载全部文件时,会调用yapi的接口获取接口列表,并遍历接口去挨个下载。

请求接口使用了axios库,调用非常方便,携带cookie直接请求完事

await axios.get(url, { headers: headers });

拿到了接口的信息后,调用json-schema-to-typescript转换,并且拼接了头部请求,和尾部api内容,完成了一个完整的api请求文件。

最后保存到对应的目录中。

npm包发布

package.json中填写包信息

配置包名、版本、描述等信息

填写bin入口文件,表示命令yt会执行./bin/index.js入口文件,而这个文件中编写的是前面commander所编写的命令行交互。

 "bin": {
    "yt": "./bin/index.js"
  },

使用npm link可以连接开发中的包,能够直接全局使用。

使用npm login登陆npm账号

使用npm publish发布npm包,值得注意的是发布的时候容易重名,导致无法发布,可以先查询是否存在同名包后再发布。

总结

开发过程中也有遇到一些问题,例如一开始使用commonjs的语法编写js,但后面发现很多库不支持,又切换到了es module。配置文件本来使用json直接存储,但是发现需要扩展的话使用json不方便,例如自定义头部尾部内容,一些地方的回调,生命周期配置,使用js能够直接编写函数插入到代码当中。

开发时间比较短,代码可能还存在一些问题,没有仔细考虑,但目前能够满足自身需求。

通过这次脚手架开发,感受到效率的提升,熟练掌握后,能够在工作中发挥更大的作用。