preface

In daily development, back-end developers will provide ****Swagger** UI, ****Yapi** and other interface description documents, and front-end developers will refer to the interface documents to write corresponding SERVICE, interface and other TS declaration codes. If the back-end interfaces all follow a RESTful style, then we can generate front-end code using nodeJS contracts to improve developer productivity and reduce rework.

This paper mainly introduces the service front-end code generated by recast translation and specification, and then extends to achieve TS declaration code generation

Prepare conditions

This article requires that you have some knowledge of Babel translation and only care about the implementation of front-end code generation. Babel related articles: juejin.cn/post/684490…

implementation

1. Obtain interface data

In official Swagger UI interface data, for example, https://petstore.swagger.io/v2/swagger.json, describes the interface url, request, the request parameters and return data

Interface data format

Focus only on three objects: Paths (API request description), Tags (Controller keyword), and Definitions (all object descriptions)

Using the NodeJS request interface, the interactive command line selects the API that you need to call in the Controller. Filter out the Paths (API) under that controller.

Code snippet

After formatting, the following Paths object data structures are retrieved (the return result concrete objects will be described in the next TS declaration file)

2. Recast generates code

The commemts node constructor is not tested. The commemts constructor is always tested in the first file. The commemt is always tested in the first file. The authors recommend using the Recast compiler, but they don’t give it much thought because of the similar usage of the two libraries. so, recast go!

  1. Parsing ast syntax tree Considering that the back-end development uses the same controller (we need the new API to be connected to the old controller), that is, the front-end project may have corresponding Service file before, and the old service file needs to be read and parsed into the syntax tree

    import { parse } from “recast”; // readFileSync const ast = parse(source, {
      sourceType: “module”,
      plugins: [“flowComments”]
    }); 
  2. **** Ast tree conversion we need to have a better understanding of the final ast tree node, with the help of astexplorer.net/, the acorn compiler to recast (@babel/paser also works, the node name is similar), the final generated code can be entered on the left. As shown in the following figure, the generated AST tree contains ImportDeclaration, ExportNamedDeclaration, and CommentLine nodes, which are constructed by functions in sequence

Construct the ImportDeclaration node and insert a new AST tree

Request import code may exist in the old service file. If the AST does not have the Request importDeclaration node, insert the import Request node (the following code will omit visit, Builders import).

ImportDeclaration**** Node constructor

Construct ExportNamedDeclaration to export the declaration node

As above, run the old AST tree to check whether **ExportNamedDeclaration ** nodes have the same declaration name. If no ExportNamedDeclaration node exists, insert ExportNamedDeclaration node

ExportNamedDeclaration Node constructor This method can accept request parameters, export method names, gateways, etc., depending on your project.

Add the commentLine comment node

The Comments expression node exists as the Comments property of the ExportNamedDeclaration node, where you simply assign the commentLine comment array node to the Comments property

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); }})Copy the code

3. Generator code construction

Similar to the usage of babel-generator, recast. Print can beautify the configuration with code. After constructing string code, it can overwrite the corresponding files of the front-end project. It can also be an existing development environment or test environment.

import { prettyPrint } from "recast"; . prettyPrint(ast, { tabWidth: 2 }).code; // Write the corresponding file...Copy the code

conclusion

Insert front-end code into the project, the whole process is more about the compatibility of old and new code, need to write more fault tolerant code, practice and find problems from the project, after many iterations will evolve into the development of accelerated front-end tools, will be added to the “Generation OF TS declaration file”

The resources

This project: github.com/rule78/reca…

Recast: github.com/benjamn/rec…

Babel: github.com/jamiebuilds…