根据swagger接口文档自动化生成前端ts声明代码

2,567 阅读3分钟

前言

日常开发中,后端开发人员会提供****Swagger** UI、****Yapi**等接口描述文档,前端发开人员则查阅接口文档编写对应的service、interface等ts声明代码。如果后端接口都遵循RESTful 风格,那么我们可以通过nodejs 约定式生成前端代码,以提高开发者效率和 减少重复的工作。

本文主要介绍通过 recast 转译并生成规范的service前端代码,后续再拓展实现ts声明代码生成

先备条件

 本文需要你对babel转译有一定了解,只关心前端代码生成的实现, Babel相关文章:juejin.cn/post/684490…

实现

  1、获取接口数据

Swagger UI官方接口数据为例 https://petstore.swagger.io/v2/swagger.json,  描述接口url、请求方式、请求参数、返回数据体

接口数据格式

只关注三个对象paths(api请求描述)、tags(controller关键字)、definitions(所有对象具体描述)

通过nodejs请求接口,交互命令行选择你所需要调用controller里面的api, 筛选出该controller下的paths ( api )

代码片段

经过格式化后,所获取到以下paths对象数据结构(返回结果具体对象将在下一篇ts声明文件中介绍)

2、recast生成代码

这里会有疑问,同样是解析、转换、构建生成前端代码为什么选择了recast,而不是大家更为熟悉的babel, 原因是@babel/types 缺少commemts(注释)node节点构造器,在github上提了issue后,作者建议使用recast编译器,由于两个库用法相近笔者也没做过多的考虑了。 so, recast go!

  1. 解析ast语法树
    考虑到后端开发有使用同一controller的情况(我们需要新对接的api属于旧controller),即前端项目在之前可能存在对应service文件,需要读取 旧service文件并解析成语法树

    import { parse } from "recast"; // 省略readFileSync代码 const ast = parse(source, {
      sourceType: "module",
      plugins: ["flowComments"]
    }); 
  2. ****ast树转换
    我们需要对最终构建出来的ast树节点有更好的认识, 借助网站astexplorer.net/,把acorn编译器切换为recast (@babel/paser也行,节点名称相似),  左边输入最终生成代码即可。 如下图,可见最终生成的ast树最外层有ImportDeclaration、ExportNamedDeclaration、CommentLine三个主要节点,通过函数依次构造

构造ImportDeclaration节点并插入新ast树

旧service文件中可能存在request引入代码,当ast不存在request importDeclaration节点时,插入引入request节点(以下代码将省略visit、builders引入)

ImportDeclaration****节点构造方法

构造ExportNamedDeclaration 导出声明节点

同上,对旧ast树遍历查询 **ExportNamedDeclaration **类型节点,是否存在相同声明名称(declaration.id),节点不存在时插入ExportNamedDeclaration node节点

ExportNamedDeclaration 节点构造方法 此方法可接受请求参数、导出方法名称、网关等参数,具体视自己项目情况(functionDeclaration节点具体实现可参考源码)

添加commentLine 注释节点

comments表达式节点 作为ExportNamedDeclaration节点的comments 属性存在,在节点上直接对comments 属性赋予 commentLine注释数组节点即可

  v(ast, {    visitProgram(path) {    ...    formatPaths(paths).forEach((i, index) => {          ...          // 添加注释          const funcNodeList = path.node.body.filter(i => i.declaration)          funcNodeList[index].comments = [t.commentLine(i.summary)]        }        return;      })      this.traverse(path);    }  })
复制代码

3、generator代码构建

与babel-generator用法相似,recast.print 可使用代码美化配置,构建字符串代码后,覆盖前端项目对应文件即可, 最后还可以将script 整合到前端cli,添加一些个性化配置,例如调用的接口服务可以是后端开发本地服务,也可以是存在的开发环境、测试环境。

import { prettyPrint } from "recast";
...
prettyPrint(ast, { tabWidth: 2 }).code;

// 写入对应文件
...
复制代码

总结