You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS Swagger插件在Monorepo共享包无法生成_OPENAPI_METADATA_FACTORY

Monorepo中@nestjs/swagger插件无法为共享DTO包自动生成元数据

问题背景

Monorepo包含一个NestJS应用、多个前端应用,以及一个用于共享DTO等类型的公共包。希望通过@nestjs/swagger插件自动生成Swagger文档,无需手动添加@ApiProperty装饰器,但共享包中的DTO编译后未生成预期的_OPENAPI_METADATA_FACTORY()方法。

正常工作场景

在NestJS应用内部定义的DTO可以正常生成元数据:

// geolocation.controller.ts
import { DummyType } from './definition/dummy-type.dto';

@Version('2')
@Post('/')
async getGeolocationV2(@Body() body: DummyType) {
  // ...
}
// definition/dummy-type.dto
export class DummyType {
  /**
   * dummy key
   */
  key: string;
}

编译后的JS文件自动生成了元数据方法:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DummyType = void 0;
const openapi = require("@nestjs/swagger");
class DummyType {
    static _OPENAPI_METADATA_FACTORY() {
        return { key: { required: true, type: () => String, description: "dummy key" } };
    }
}
exports.DummyType = DummyType;
//# sourceMappingURL=dummy-type.dto.js.map

异常场景

使用共享包中的DTO时,编译后未生成元数据方法:

// geolocation.controller.ts
import { GeocodingRequestBody } from 'my-shared-package';

/**
 * return geolocation coordinates based on a address
 */
@Version('3')
@Post('/')
async getGeolocationV3(@Body() body: GeocodingRequestBody) {
  // ...
}
// my-shared-package/.../geolocation-request.dto.ts
export class GeocodingRequestBody {
  /**
   * dummy value
   */
  property_one: string;
}

编译后的JS文件无_OPENAPI_METADATA_FACTORY():

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GeocodingRequestBody = void 0;
const openapi = require("@nestjs/swagger");
class GeocodingRequestBody {
}
exports.GeocodingRequestBody = GeocodingRequestBody;
//# sourceMappingURL=geolocation-request.dto.js.map

现有配置

共享包使用Nest CLI编译,命令:

barrelsby --delete -c barrelsby.json && nest build --path tsconfig.json --config nest-cli.json

主应用和共享包的nest-cli.json配置一致:

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": [
      {
        "name": "@nestjs/swagger",
        "options": {
          "introspectComments": true,
          "controllerKeyOfComment": "summary"
        }
      }
    ]
  }
}

tsconfig.json配置一致:

{
  "include": ["src/**/*"],
  "compilerOptions": {
    "module": "commonjs",
    "target": "es2017",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "strict": false,
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "ignoreDeprecations": "5.0",
    "paths": {},
    "incremental": true,
    "skipLibCheck": true,
    "types": ["node"],
    "resolveJsonModule": true
  }
}

解决思路

  1. 确认共享包的插件加载状态

    • 检查共享包的@nestjs/swagger依赖是否安装为devDependencies(编译时插件无需作为生产依赖),且版本与主应用完全一致。
    • 在共享包的nest-cli.json插件配置中添加"dtoFileNameSuffix": [".dto.ts"],明确指定DTO文件后缀,确保插件精准识别目标文件:
      "plugins": [
        {
          "name": "@nestjs/swagger",
          "options": {
            "introspectComments": true,
            "controllerKeyOfComment": "summary",
            "dtoFileNameSuffix": [".dto.ts"]
          }
        }
      ]
      
  2. 排查编译流程干扰

    • 暂时禁用barrelsby,直接执行nest build编译共享包,检查单个DTO文件是否生成元数据,排除自动生成的index文件对插件的干扰。
    • 简化编译命令,去掉--path和--config参数,使用默认配置文件测试,确认命令是否正确读取配置。
  3. 验证TS配置细节

    • 临时将tsconfig.json中的removeComments改为false,编译后检查是否生成元数据——若生效则说明注释被提前移除导致插件无法识别JSDoc。
    • 确认emitDecoratorMetadata和experimentalDecorators始终为true,避免编译时配置被覆盖。
  4. 手动触发插件调试

    • 在共享包的DTO类中添加一个空装饰器,确认插件是否能识别到该类,排除插件未处理共享包文件的情况。

内容的提问来源于stack exchange,提问作者Clément Vannouque

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 04:35:54