Il plugin CLI

La soluzione consigliata per webpack: true, automatica, a ogni build, senza uno step separato da ricordare.

È lo stesso meccanismo che il plugin CLI di @nestjs/swagger stesso usa per funzionare sotto webpack: true. Per questo @ApiProperty() non è richiesto su ogni proprietà DTO nemmeno in una build webpack. La Nest CLI passa un hook di plugin del compilatore TypeScript (compilerOptions.plugins) sia a tsc sia al builder webpack (ts-loader) in modo identico.

Registra il plugin

Registra nestjs-docfy in 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));

Rilevamento automatico

Dimenticare di registrare il plugin è facile da non notare finché una build non viene rilasciata senza documentazione, quindi ogni esecuzione di generate controlla già nest-cli.json e stampa un avviso quando webpack: true è impostato senza il plugin. Passa --register-plugin per farglielo correggere al posto tuo invece di modificare il file a mano:

bash
npx nestjs-docfy generate --register-plugin

Questo è opt-in di proposito, dato che alcuni team scelgono deliberatamente patch-spec invece di un plugin del compilatore, quindi generate non modifica mai nest-cli.json a meno che tu non lo chieda esplicitamente. Aggiunge un'entry a qualsiasi array compilerOptions.plugins esistente (riconoscendo sia le voci in forma stringa sia in forma oggetto come già registrate) e rispetta --dry-run.

Come funziona

Il plugin di nestjs-docfy non riscrive alcuna sintassi di decorator né tocca l'AST. A ogni compilazione riesegue esattamente la stessa analisi statica che generate/check/patch-spec già fanno (tramite ts-morph, contro l'albero sorgente, non il bundle) e scrive la patch risultante in docfy-metadata.json accanto all'output di build.

Poi, subito dopo SwaggerModule.createDocument(), applyDocfyMetadata() legge quel file e la unisce. Non c'è alcun coinvolgimento di require.cache né alcun problema di identità di classe bundlata, perché non ha mai bisogno dell'app in esecuzione per calcolare nulla.

vs. patch-spec

Manual, CI-driven alternative

Se preferisci non aggiungere un plugin del compilatore (ad esempio, una pipeline di build che non è la Nest CLI, o una policy più severa su cosa gira durante la compilazione), patch-spec calcola a mano la patch identica su un documento già costruito. Era l'unica opzione prima che esistesse il plugin, e resta utile per patch una tantum.