Skip to content

[Bug]: 当 swagger 文档接口数量增长到一定程度后,使用 @alova/wormhole 生成代码时非常慢,甚至可能失败 #136

Description

@PrinzEugenCz

这是否是一个 Bug?

  • 我已经确认我要报告的是一个 Bug

这个问题是否已经存在?

  • 我已经确认这个 Issue 没有被报告过

Alova 版本

3.3.4

前端框架

React

问题描述

我在我的项目中使用了 @alova/wormhole 在前端自动生成接口请求代码。起先它工作的非常正常,在几秒钟的时间内就迅速的生成了代码。但随着接口数量的逐渐增多,代码生成的时间逐渐变成了1分钟、2分钟,直到现在需要整整5分钟才能生成完毕(500多个接口)。甚至现在在低性能的机器上,代码有可能生成失败。

期望的表现

可以降低代码生成所需要的时间

复现链接

No response

复现步骤

使用 alova 插件正常执行代码生成操作

系统信息

  System:
    OS: Windows 11 10.0.26100
    CPU: (32) x64 AMD Ryzen 9 7940HX with Radeon Graphics
    Memory: 7.38 GB / 31.22 GB
  Binaries:
    Node: 18.20.7 - C:\Program Files\nodejs\node.EXE
    npm: 10.8.2 - C:\Program Files\nodejs\npm.CMD
    pnpm: 10.4.1 - C:\Program Files\nodejs\pnpm.CMD
  Browsers:
    Chrome: 142.0.7444.177
    Edge: Chromium (140.0.3485.54)

补充说明

我的 @alova/wormhole 版本是 1.5.0
这是我的 alova.config.ts ,我尝试着通过配置去除了 globals.d.ts 中生成出来的大量注释,因为它会把整个文件的内容量撑到几百万行代码,并把我的编辑器卡爆 :-D。我有理由相信为了生成这些注释所做的操作是导致代码生成需要耗费如此夸张的时间的原因,因为当我去除掉这些配置后,globals.d.ts 中就只剩下了 17000 行代码:

import type { Config } from '@alova/wormhole';
import alovaLocal from './alova.local';

// For more config detailed visit:
// https://alova.js.org/tutorial/getting-started/extension-integration
export default {
  generator: [
    {
      /**
       * file input. support:
       * 1. openapi json file url
       * 2. local file
       */
      // input: 'http://127.0.0.1:8080/swagger/doc.json',
      input: alovaLocal.input,

      /**
       * input file platform. Currently only swagger is supported.
       * When this parameter is specified, the input field only needs to specify the document address without specifying the openapi file
       */
      platform: 'swagger',

      /**
       * output path of interface file and type file.
       * Multiple generators cannot have the same address, otherwise the generated code will overwrite each other.
       */
      output: 'src/api',

      /**
       * the mediaType of the generated response data. default is `application/json`
       */
      // responseMediaType: 'application/json',

      /**
       * the bodyMediaType of the generated request body data. default is `application/json`
       */
      // bodyMediaType: 'application/json',

      /**
       * the generated api version. options are `2` or `3`, default is `auto`.
       */
      // version: 'auto',

      /**
       * type of generated code.The options are `auto/ts/typescript/module/commonjs`.
       */
      type: 'module',

      /**
       * exported global api name, you can access the generated api globally through this name, default is `Apis`.
       * it is required when multiple generators are configured, and it cannot be repeated
       */
      // global: 'Apis',

      /**
       * filter or convert the generated api information, return an apiDescriptor, if this function is not specified, the apiDescripor object is not converted
       */
      handleApi: (apiDescriptor) => {
        if (apiDescriptor.operationId) {
          apiDescriptor.operationId = toPascalCase(apiDescriptor.operationId);
        }
        if (apiDescriptor.tags) {
          apiDescriptor.tags = apiDescriptor.tags.map(item => toPascalCase(item));
        }
        if (apiDescriptor.responses) {
          // apiDescriptor.responses.properties = {};
          // delete apiDescriptor.responses.properties;
        }
        if (apiDescriptor.requestBody) {
          // apiDescriptor.requestBody.properties = {};
          // delete apiDescriptor.requestBody.properties;
        }

        return apiDescriptor;
      },

      plugins: [{
        beforeCodeGenerate: (data) => {
          data?.pathApis?.forEach((pathApi: any) => {
            pathApi.apis?.forEach((api: any) => {
              api.responseComment = '';
              api.requestComment = '';
            });
          });
          // console.log('??', data);
        },
      }],
    },
  ],

  autoUpdate: false,
  /**
   * extension only
   * whether to automatically update the interface, enabled by default, check every 5 minutes, closed when set to `false`
   */
  // autoUpdate: true
} as Config;

/**
 * 将任意字符串转换为大驼峰命名格式 (PascalCase)
 * @param {string} str - 输入字符串
 * @returns {string} - 转换后的大驼峰字符串
 */
function toPascalCase(str: string) {
  if (!str || typeof str !== 'string') {
    return '';
  }

  return str
    // 处理小驼峰:在大写字母前插入分隔符
    .replace(/([a-z])([A-Z])/g, '$1 $2')
    // 处理连续大写字母:HTML -> H T M L
    .replace(/([A-Z])([A-Z][a-z])/g, '$1 $2')
    // 将字符串按非字母数字字符分割
    .split(/[^a-zA-Z0-9]+/)
    // 过滤掉空字符串
    .filter(word => word.length > 0)
    // 将每个单词的首字母大写,其余小写
    .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
    // 连接所有单词
    .join('');
}

如果有需要的话,我可以把我的 swagger.json 文档发给你们。但是我似乎没有找到官方的邮箱地址。

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions