仕組み
モンキーパッチなし、ランタイムプロキシなし。正しいタイミングとReflectメタデータだけです。
パイプライン
DocfyModule.forRoot()はNestFactory.create()フェーズの間、SwaggerModule.createDocument()が呼び出される前に同期的に実行されます。require()を使って各コンパニオンdocsファイルを読み込み、これがdocs()を実行して、TypeScriptのデコレーター構文がクラス定義時に行うのとまったく同じように、Reflectメタデータをコントローラーのメソッドへ直接書き込みます。
SwaggerModule.createDocument()がメタデータをスキャンする頃には、すべてがすでに整っています。モンキーパッチなし、ランタイムプロキシなしです。
タイミング
重要なタイミングの気づき
onModuleInitやその他のライフサイクルフックは、main.tsでSwaggerModule.createDocument()がすでに呼び出された後に発火します。onModuleInitに基づくアプローチは、空のSwaggerドキュメントを生成してしまいます。nestjs-docfyがその経路を避け、NestFactory.create()の間に実行される同期的なrequire()をforRoot()の内部で使っているのはそのためです。これはどのライフサイクルフックやSwaggerModuleの呼び出しよりも前に実行されます。
CLI: 静的解析
generate CLIは静的解析にts-morphを使います。プロジェクトのコードを一切実行せず、TypeScriptのASTを読み取ります。ユーザーが指定したすべてのパスとglobパターンは、使用前に検証・サニタイズされます。