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:
{
"compilerOptions": {
"webpack": true,
"plugins": ["nestjs-docfy"]
}
}import { applyDocfyMetadata } from 'nestjs-docfy';
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, applyDocfyMetadata(document));| Option | Type | Default | Description |
|---|---|---|---|
metadataPath | string | docfy-metadata.json next to the running entry file | Where to read the plugin-generated metadata from. |
strict | boolean | false | Throw instead of warning when the metadata file is missing or invalid. |
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:
npx nestjs-docfy generate --register-pluginQuesto è 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
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.
Builder SWC
@nestjs/cli tratta il builder SWC in modo diverso. Non chiama mai before() sotto "builder": "swc", solo un ReadonlyVisitor, e solo quando "typeCheck": true è impostato anche lui (altrimenti SWC salta del tutto il controllo dei tipi per conto suo). Questo plugin esporta entrambi gli hook, quindi attivare quell'opzione basta:
{
"compilerOptions": {
"builder": "swc",
"typeCheck": true,
"plugins": ["nestjs-docfy"]
}
}Una cosa da sapere: registrare il plugin in questo modo scrive un file metadata.ts accanto alla radice del tuo source a ogni build. È lo stesso artefatto che il supporto SWC di @nestjs/swagger produce già lì, vuoto e innocuo se anche quel plugin non è registrato.
Ometti typeCheck e il plugin resta semplicemente in silenzio. Il build continua a riuscire, ma nessun docfy-metadata.json viene scritto e applyDocfyMetadata() non ha nulla da unire. generate intercetta esattamente questa combinazione e avvisa.
Niente di tutto questo tocca la discovery a runtime di DocfyModule. Funziona sotto SWC esattamente come sotto tsc, dato che SWC continua a compilare un file per modulo e require.cache finisce popolato allo stesso modo. Se impostare typeCheck non è un'opzione, @WithDocs() insieme a DocfyModule.forRoot() ti ci porta comunque, senza il plugin.