O plugin do CLI
A correção recomendada para webpack: true, automática, a cada build, sem etapa separada pra lembrar.
É o mesmo mecanismo que o próprio plugin de CLI do @nestjs/swagger usa para funcionar sob webpack: true. É por isso que @ApiProperty() não é necessário em toda propriedade de DTO mesmo em um build webpack. O Nest CLI alimenta um hook de plugin de compilador TypeScript (compilerOptions.plugins) tanto no builder tsc quanto no webpack (ts-loader), de forma idêntica.
Registre o plugin
Registre o nestjs-docfy no 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. |
Detecção automática
É fácil esquecer de registrar o plugin até um build sair sem documentação, então toda execução de generate já lê o nest-cli.json e imprime um aviso quando webpack: true está configurado sem o plugin. Passe --register-plugin pra corrigir isso automaticamente em vez de editar o arquivo à mão:
npx nestjs-docfy generate --register-pluginIsso é opt-in de propósito, já que alguns times ficam deliberadamente com o patch-spec em vez de um plugin de compilador, então o generate nunca edita o nest-cli.json a menos que você peça explicitamente. Ele adiciona ao array compilerOptions.plugins já existente (reconhecendo entradas tanto em string quanto em objeto como já registradas) e respeita --dry-run.
Como funciona
O plugin do nestjs-docfy não reescreve nenhuma sintaxe de decorator nem toca na AST. A cada compilação, ele roda de novo a mesma análise estática que generate/check/patch-spec já fazem (via ts-morph, na árvore de source, não no bundle) e escreve o patch resultante em docfy-metadata.json ao lado do output do build.
Aí, logo após SwaggerModule.createDocument(), o applyDocfyMetadata() lê esse arquivo e mescla nele. Não há require.cache envolvido nem problema de identidade de classe de bundle, porque nunca precisa da app em execução pra calcular nada.
vs. patch-spec
Se você preferir não adicionar um plugin de compilador (por exemplo, um pipeline de build que não é o Nest CLI, ou uma política mais rígida sobre o que roda durante a compilação), o patch-spec computa o mesmo patch manualmente contra um documento já buildado. Essa era a única opção antes do plugin existir, e continua útil para patches pontuais.
Builder SWC
O @nestjs/cli trata o builder SWC de um jeito diferente. Ele nunca chama before() sob "builder": "swc", só um ReadonlyVisitor, e só quando "typeCheck": true também está setado (senão o SWC pula a checagem de tipos por conta própria). Esse plugin exporta os dois hooks, então ligar essa opção é tudo que precisa:
{
"compilerOptions": {
"builder": "swc",
"typeCheck": true,
"plugins": ["nestjs-docfy"]
}
}Uma coisa vale saber: registrar o plugin desse jeito escreve um arquivo metadata.ts ao lado da raiz do seu source a cada build. É o mesmo artefato que o suporte a SWC do próprio @nestjs/swagger já produz ali, vazio e inofensivo se aquele plugin não estiver registrado também.
Deixe de fora o typeCheck e o plugin simplesmente fica quieto. O build continua funcionando, mas nenhum docfy-metadata.json é escrito e o applyDocfyMetadata() não tem nada pra mesclar. O generate pega exatamente essa combinação e avisa.
Nada disso afeta a discovery em runtime do DocfyModule. Ela funciona sob SWC exatamente como sob tsc, já que o SWC ainda compila um arquivo por módulo e o require.cache acaba populado do mesmo jeito. Se setar o typeCheck não for uma opção, @WithDocs() junto com DocfyModule.forRoot() ainda te leva lá sem o plugin.