tl;dr
typedoc-plugin-merge-modules ってプラグインにモジュールをいい感じでまとめる Pull Request を送ったら採用されたので使ってください。利用方法のサンプルレポジトリも用意しました
yarn add --dev typedoc typedoc-plugin-merge-modules
yarn typedoc
var { sync } = require("glob");
const { resolve } = require("path");
module.exports = {
entryPoints: sync(resolve("src/**/*{.js,.ts}")),
out: "docs/",
categorizeByGroup: true,
mergeModulesMergeMode: "module", // ← これを追加してください
};
標準のモジュール名解決
TypeDoc のモジュール名解決は全自動でやってくれるんですが、かなり原始的で、ファイルごとにモジュールとして認識されてしまいます。これは、フォルダ内に 1関数1ファイルで実装して index.ts
で一括 re-export とかしている場合に非常に不便です
export function module2functionA(): void {
console.log("do nothing");
}
export function moduleFunctionB(): void {
console.log("do nothing");
}
/**
* module with re-export index with multiple files with single function export
* @packageDocumentation
* @module module
*/
export * from "./functionA";
export * from "./functionB";
↓↓↓
module
module/functionA
module/functionB
@module
ディレクティブ
TypeDoc には @module
というディレクティブ が定義されており、該当ファイルのモジュール名を明示的に指定できます
しかし、残念なことにモジュール名の重複は想定しておらず、以下のように同じモジュール名が並びリンク先がひとつになり、情報が欠けてしまいます
module
module
module
プラグインを求めて
v19 系では typedoc-plugin-external-module-name
というプラグインがいい感じにしてくれたようなのですが、 2021-06-08 時点では v20 に対応しておらず、すなわちそれは TypeScript 4 にも未対応ということで哀しい気持ちになってしまいます
FWIW - this plugin is likely partially obsolete with 0.20.
AssertionError: "Tried to access Context.program when not converting a source file." · Issue #587 · christopherthielen/typedoc-plugin-external-module-name
そもそも External Module Name
プラグインはディレクトリ構造とモジュール名の対応付けを行うためのプラグインで、その機能が v20 で標準に組み込まれたため、メンテナンスするモチベーションがなくなるのはわかります。でも違う、ぼくが欲しいのはモジュールの統合機能であってそっちだけでちゃんと動いて欲しかった
v19 で同じソースコードを出力するとそれなりにいい感じになります
無いなら作ればいい
他にいいプラグインはないかと探してみたんですがそれっぽいのは見つからず、唯一見つけたのが typedoc-plugin-merge-modules で、このプラグインは元々、モジュール分割を完全にフラットにする、というものでした
雑にソースコードを読んだ感じいけるのではないか、、、ということで、サクッとオプションを追加して PR を投げてみたところ、すんなりとマージされて公開されました
プラグインをインストールすると typedoc
コマンド実行時に自動で読み込まれるようになります
yarn add --dev typedoc-plugin-merge-modules
標準ではすべての export
がフラットになるため、 mergeModulesMergeMode
オプションに "module"
を設定します
var { sync } = require("glob");
const { resolve } = require("path");
module.exports = {
entryPoints: sync(resolve("src/**/*{.js,.ts}")),
out: "docs/",
categorizeByGroup: true,
mergeModulesMergeMode: "module", // ← これを追加してください
};
これで @module
ディレクティブで指定されたモジュールの重複をまとめてひとつにしてくれます
サンプルレポジトリについて
よくある構成ごとにパターンを用意しています
モジュール名 | 構成 |
---|---|
module1 | module/index.ts の中に複数の export |
module2 | module/index.ts は re-export 。関数の実態は別ファイル |
module3 | フォルダ分けせずに module.ts の中に複数の export |
module4 | module2 のパターンにサブモジュールを追加 ※ |
※ module3/index.ts で module4/submodule を re-export しているがドキュメント上は影響なし
各設定はブランチで分けています
ブランチ名 | 内容 |
---|---|
v20-with-plugin(デフォルト) |
typedoc-plugin-merge-modules を導入したもの |
v20 | v20 の標準 |
20-bad | v20 に @module ディレクティブを指定したもの |
v19 | v19 に typedoc-plugin-external-module-name を導入したもの |