File naming convention
Discovery is automatic. DocfyModule locates each controller's source file via Node's module cache.
Convention
Discovery is automatic. DocfyModule locates each controller's source file via Node's module cache and resolves the companion path: this works identically under ts-node (development) and compiled dist/ (production).
| Controller file | Companion file |
|---|---|
users.controller.ts | users.controller.docs.ts |
users.controller.js | users.controller.docs.js |
Barrel re-exports
If your controller is also exported from a barrel index.ts, make sure the class is exported directly from its own module file. nestjs-docfy prefers .controller.ts over barrel files.
Not supported: the NestJS CLI's webpack: true build mode
If your nest-cli.json has "webpack": true under compilerOptions (the documented default for monorepos with multiple apps), nestjs-docfy will not work, and there is no configuration that makes it work. This is architectural, not a bug to be fixed:
- Webpack inlines every module into a single bundle file and never populates Node's
require.cachewith one entry per original source file, which is what the discovery mechanism depends on. You'll seeCould not locate source file for Xfor every controller with@WithDocs(). - Even if that lookup is worked around (for example, by recovering the original path from the bundle's source map, skipping
require.cache), there's an unavoidable second wall: a docs file required from outside the bundle creates a class object that is structurally different from the one the running app uses internally. Decorating that fresh copy has no effect on the document thatSwaggerModule.createDocument()actually serves. This happens silently, with no error. - The only way around this would be for the controller file itself to import its
.docs.tscompanion (forcing webpack to bundle both together), which defeats the entire point of the convention: zero coupling between controller and documentation.
How to resolve it
If you need nestjs-docfy, disable webpack bundling: remove "webpack": true (or set it to false) in nest-cli.json. Under the default tsc-based compilation, every source file (including every *.controller.docs.ts) is compiled to its own .js in dist/, so require.cache naturally has one entry per file and discovery works.
If you can't turn off webpack, use the patch-spec command as an alternative flow.