El plugin de CLI

El fix recomendado para webpack: true, automático, en cada build, sin ningún paso aparte que recordar.

Este es el mismo mecanismo que usa el propio plugin de CLI de @nestjs/swagger para funcionar bajo webpack: true. Por eso @ApiProperty() no es obligatorio en cada propiedad de un DTO incluso en un build con webpack. El Nest CLI alimenta un hook de plugin de compilador TypeScript (compilerOptions.plugins) tanto al builder tsc como al de webpack (ts-loader) de forma idéntica.

Registra el plugin

Registra nestjs-docfy en nest-cli.json:

nest-cli.json
{
  "compilerOptions": {
    "webpack": true,
    "plugins": ["nestjs-docfy"]
  }
}
main.ts
import { applyDocfyMetadata } from 'nestjs-docfy';

const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, applyDocfyMetadata(document));

Detección automática

Olvidar registrar el plugin es fácil de pasar por alto hasta que un build sale sin documentación, así que cada ejecución de generate ya comprueba nest-cli.json e imprime un aviso cuando webpack: true está activado sin el plugin. Pasa --register-plugin para que lo arregle por ti en vez de editar el archivo a mano:

bash
npx nestjs-docfy generate --register-plugin

Esto es opt-in a propósito, ya que algunos equipos se quedan deliberadamente con patch-spec en vez de un plugin de compilador, así que generate nunca edita nest-cli.json a menos que se lo pidas explícitamente. Añade al final de cualquier array compilerOptions.plugins existente (reconociendo entradas tanto en forma de string como de objeto como ya registradas) y respeta --dry-run.

Cómo funciona

El plugin de nestjs-docfy no reescribe ninguna sintaxis de decorator ni toca el AST en absoluto. En cada compilación vuelve a ejecutar exactamente el mismo análisis estático que ya hacen generate/check/patch-spec (vía ts-morph, contra el árbol fuente, no el bundle) y escribe el patch resultante en docfy-metadata.json junto a la salida del build.

Luego, justo después de SwaggerModule.createDocument(), applyDocfyMetadata() lee ese archivo y lo fusiona. No hay ningún require.cache involucrado ni problema de identidad de clase en el bundle, porque nunca necesita que la app en ejecución calcule nada.

vs. patch-spec

Manual, CI-driven alternative

Si prefieres no añadir un plugin de compilador (por ejemplo, un pipeline de build que no es el Nest CLI, o una política más estricta sobre qué se ejecuta durante la compilación), patch-spec calcula el mismo patch a mano contra un documento ya construido. Esa era la única opción antes de que existiera el plugin, y sigue siendo útil para parcheos puntuales.