codependix-configure について
Nx ワークスペースでの Codependix のグラフ出力と境界チェックを設定するスキルです。出力先、プロジェクト選択、個別設定、検証ルールを説明します。
主な機能
- 01グラフ出力先の指定
- 02JSON または Markdown の選択
- 03include と exclude の glob による選択
- 04プロジェクト別グラフ設定
- 05グラフ境界ルールの定義
活用シーン
- 01ワークスペースプロジェクトの出力設定
- 02Markdown のアンカーやファイルへの出力
- 03出力対象からのプロジェクト除外
- 04境界チェック用依存ルールの追加
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ organizzolini/ codebase --skill codependix-configureインストール後、Claude Code で/codependix-configureを入力して読み込まれたか確認します。
詳細
codependix 設定の記述
設定でエクスポートする内容と出力先を指定するまで、Codependix は何も生成しません。ファイル内のすべてのフィールドは省略可能ですが、ファイル自体は省略できません。実行時には必ず --config <path> で設定ファイルを指定します(このリポジトリでは、--config configuration/codependix.config.ts)。指定しない実行は拒否されます。include を省略した設定では、すべてのプロジェクトのすべてのグラフタイプが target: "none" に解決されます。つまり、実行は成功しますが、何も書き出されません。設定が唯一の制御手段であり、グラフタイプを選択するフラグはありません。
import { type CodependixConfiguration } from "@codependix/configuration";
const codependixConfiguration: CodependixConfiguration = {
defaults: {
imports: { markdown: { anchor: "codependix-file-imports" }, target: "markdown" },
nestjs: { markdown: { anchor: "codependix-nestjs-modules" }, target: "markdown" },
nx: { markdown: { anchor: "codependix-nx-projects" }, target: "markdown" },
},
exclude: ["fixtures/**"],
include: ["**"],
projects: {
widgets: {
nx: {
json: { path: "output/nx-graph.json" },
markdown: { anchor: "codependix-nx-projects", path: "docs/architecture.md" },
target: "both",
},
},
},
workspace: {
nx: { markdown: { anchor: "codependix-workspace" }, target: "markdown" },
},
};
export default codependixConfiguration;
ファイルの場所
検索されません。ファイル名を指定します。--config <path> は必須で、デフォルトのファイル名も、検索も、親ディレクトリへの遡りもありません。そのため、codependix map --write --config configuration/codependix.config.ts はそのファイルだけを読み込みます。ts、mts、cts、js、mjs、cjs、json のいずれかの拡張子を読み込めます。同じ場所にある別のファイルが代わりに読み込まれることはありません。
--configで指定するパスは存在している必要があります。 タイプミスがあると、すべてのグラフが"none"に静かに解決されるのではなく、実行が失敗します。まず作業ディレクトリを基準に解決し、次にワークスペースのルートを基準に解決します。そのため、configuration/フォルダーに置いた設定を、どちらの場所からの相対パスでも指定できます。--configを指定しない場合も、実行は失敗します。 このフラグは必須です。省略すると、--configを示すエラーで拒否され、ワークスペースのルートにあるcodependix.config.tsにフォールバックすることもありません。
プロジェクト独自の codependix.config.ts は、ファイル名を指定せずに見つけられる唯一のファイルです。プロジェクトのルートと同じ場所から読み込まれ、親ディレクトリから読み込まれることはありません。このファイルがないプロジェクトでは、プロジェクトごとの出力は生成されません。
default ではなく defaults
独自のオーバーライドを指定しないすべてのプロジェクトに適用されるフィールド名は、defaults です。設定モジュールのデフォルトエクスポートは、読み込み時に名前で展開されるため、default というフィールド名はその展開と衝突します。default: を記述しても、設定が拒否されるわけではありません。未知のキーは拒否されずに取り除かれるため、新しい設定も古い codependix で読み込めます。ただし、まったく効果がなく、ツールに無視されたかのように見えます。
target は明示的に指定します
各グラフタイプのエクスポート先は、存在する出力先から推測されるのではなく、名前で指定します。
target | 書き出される内容 |
|---|---|
"both" | JSON と Markdown の出力先の両方 |
"json" | JSON の出力先のみ |
"markdown" | Markdown の出力先のみ |
"none" | 何も書き出しません。未設定の target のデフォルトです |
このように明示することで、まだ書き出す準備ができていない json の出力先をプロジェクトに残しておけます。その場合は、出力先をそのままにして target: "markdown" を設定します。
設定は検証され、次の2つの不整合は無視されずに拒否されます。
jsonの出力先がない状態で"both"または"json"を指定する場合。markdownの出力先がない状態で"both"または"markdown"を指定する場合。
Markdown には2つの形式があります
// Anchor mode — spliced into a named block inside an existing file.
{ markdown: { anchor: "codependix-nx-projects" }, target: "markdown" }
// Anchor mode, in a file other than the default README.md.
{ markdown: { anchor: "codependix-nx-projects", path: "docs/graphs.md" }, target: "markdown" }
// Standalone mode — the export is the whole contents of the file.
{ markdown: { path: "output/graph.md" }, target: "markdown" }
anchorを指定すると、pathのファイル内にある2つのコメントマーカーの間にエクスポート内容が挿入されます。pathのデフォルトはREADME.mdです。プロジェクト独自の readme が一般的な用途なので、毎回指定し直す必要はありません。anchorを省略すると、エクスポート内容が単独ファイルの全内容として書き出されます。この場合、pathは必須です。codependix が完全に管理するファイルについては、推測できる適切なデフォルトがありません。- どちらも指定されていない
markdownの出力先は拒否されます。エクスポート先を示すものが何もないためです。
アンカーブロックがない場合は、--write 時に自動作成されるため、あらかじめ手動で配置する必要はありません。新しいブロックがどこに作成され、どのような場合に失敗するかについては、codependix-triage スキルを参照してください。
両方の出力先のパスはプロジェクト独自のルートを基準に解決されるため、プロジェクト名を指定せずに、1つの defaults エントリーですべてのプロジェクトを設定できます。ワークスペース全体のグラフは、ワークスペースのルートを基準に解決されます。
include と exclude
どちらも、プロジェクトの Nx 名とワークスペース相対のルートに対して照合される glob のリストです。そのため、どちらの表記も使えます。
{ exclude: ["examples/**", "*-fixtures"], include: ["**"] }
include のデフォルトはなし、exclude のデフォルトは空です。そのため、どちらも省略すると、どのプロジェクトも対象にならず、実行時に何もエクスポートされません。対象にするプロジェクトは必ず指定します。ワークスペース全体を対象にするには、include: ["**"] と記述します。プロジェクトは、少なくとも1つの include glob がその名前またはルートに一致し、かつ exclude glob がどちらにも一致しない場合に含まれます。
--projects と --tags をコマンドラインから指定すると、対象を広げられます。どちらかのリストに名前があるプロジェクトは、include glob に一致しなくても対象になります。ただし、exclude はどちらにも優先されます。codependix-export を参照してください。
defaults を指定しているのに include がない設定には注意が必要です。何もエクスポートされず、終了コードは 0 のままです。また、--check boundaries は include に関係なくすべてのプロジェクトを評価します。--projects と --tags で指定したプロジェクトについても同様のため、ゲートは成功したままになります。この状態が発生すると、エクスポート実行時に警告が表示されます — 🕸️ Selected no project to export。
除外されたプロジェクトは、defaults や独自の projects エントリーの内容にかかわらず、すべてのグラフ種別で target: "none" として解決されます。そのため、プロジェクトを除外するには1行追加するだけで済み、各オーバーライドを個別に "none" へ書き換える必要はありません。
プロジェクトのオーバーライドは置き換えであり、マージではありません
projects エントリーでグラフ種別を指定すると、そのエントリーは該当するグラフ種別の defaults エントリーを完全に置き換えます。フィールドごとにマージされるわけではありません。markdown を省略して Markdown エクスポートを無効にしたプロジェクトに、デフォルトの markdown 出力先が再び適用されることはありません。
実際には、オーバーライドで引き続き使いたいすべての出力先を、target も含めて再指定する必要があります。
{
defaults: { nx: { markdown: { anchor: "codependix-nx-projects" }, target: "markdown" } },
projects: {
// Loses the Markdown export entirely — this is the whole nx entry now.
widgets: { nx: { json: { path: "graph.json" }, target: "json" } },
// Keeps both, because both are restated.
gadgets: {
nx: {
json: { path: "graph.json" },
markdown: { anchor: "codependix-nx-projects" },
target: "both",
},
},
},
}
オーバーライドで指定していないグラフ種別は、引き続き defaults にフォールバックします。置き換えはプロジェクト単位ではなく、グラフ種別ごとに行われます。
ワークスペース全体のグラフ
workspace は defaults や projects とは別であり、nx のみを指定できます。
{ workspace: { nx: { markdown: { anchor: "codependix-workspace" }, target: "markdown" } } }
ワークスペース全体の NestJS グラフや import グラフを設定することはできません。ワークスペースグラフはリポジトリごとに一度だけエクスポートされ、プロジェクトごとのオーバーライドはなく、include と exclude の影響を受けません。プロジェクト単位のエクスポートからプロジェクトを除外しても、ワークスペースグラフからは削除されません。
例外は --projects と --tags です。出力先ではなく、ノードの集合を介してワークスペースグラフにも適用されます。選択対象を指定して実行すると、指定したプロジェクトでグラフを作成し、workspace.nx で指定された場所に書き込みます。両方のフラグについては codependix-export を参照してください。
projectGraph — グラフの解決ではなく読み込み
{ projectGraph: "artifacts/graph.json" }
ワークスペースルートからの相対パスで、nx graph --file=graph.json が出力する JSON ファイルを指定します。指定すると、プロセスの作業ディレクトリにあるグラフを解決する代わりに、そのファイルを読み込みます。プロセスが現在いる場所とは異なるワークスペースのグラフを作成する唯一の方法です。省略した場合、動作は変わりません。
このファイルは信頼されます。プロジェクトグラフではないファイルのみ拒否されます。この方法で何が対象となり、何が対象とならないかについては codependix-export を参照してください。
プロジェクトに存在しないグラフ種別を設定してもコストはかかりません
NestJS プロジェクトではないプロジェクトが NestJS の処理に含まれることはありません。また、tsconfig.json のないプロジェクトが TypeScript import の処理に含まれることもありません。どちらも失敗ではなく、オーバーライドも不要です。そのため、4種類すべてのグラフ種別を指定した単一の defaults ブロックは、対象範囲が広すぎる設定ではなく、ワークスペース全体を設定する通常の形式です。
boundaries — グラフが準拠すべきルール
defaults と projects は、エクスポートの書き込み先を指定します。boundaries は、同じ4つのグラフレベルごとに、グラフがどのような状態であるべきかを指定します。適用するには、--check reports ではなく --check boundaries を指定します。
const codependixConfiguration: CodependixConfiguration = {
boundaries: {
imports: [
{
from: { path: ["**/*.types.ts"] },
kind: "forbid",
message: "Types are the leaf of a module.",
name: "types-files-do-not-reach-services",
to: { path: ["**/*.service.ts"] },
},
],
nx: [
{
from: { tags: ["type:application"] },
kind: "forbid",
name: "applications-are-leaves",
to: { tags: ["type:application"] },
},
{ kind: "acyclic", name: "no-project-cycles" },
],
},
};
種類は3つあります。
| 種類 | 検証内容 |
|---|---|
forbid | ソースが from に一致し、ターゲットが to に一致するエッジ |
allow | from から出るエッジのうち、to が対象としていないすべての行き先へのもの |
acyclic | nodes が選択するノード間の循環。指定がない場合はすべてのノードが対象 |
セレクターの4つのフィールドはすべて glob のリストで、互いに対象を絞り込みます。セレクターで指定した各フィールドが一致する必要があり、各フィールド内では glob のいずれか1つが一致すれば十分です。
| フィールド | 対象 | 適用レベル |
|---|---|---|
id | ノードの識別子 — プロジェクト名、ファイルパス、モジュールのクラス名 | すべてのレベル |
path | ワークスペース相対のプロジェクトルート、またはプロジェクト相対のファイルパス | nx、imports、pythonImports |
project | ノードが属する Nx プロジェクト | nx、imports、pythonImports |
tags | ノードの Nx タグ。いずれか1つのタグが一致すれば十分 | nx |
アクセスルールでは、edges を使って検証対象のエッジをさらに絞り込めます。
{ implicit: false } は、インポート文に基づくエッジだけを対象にします。これは @nx/enforce-module-boundaries の depConstraint が対象とするものとまったく同じです。一方、{ implicit: true } は、implicitDependencies のエントリーで宣言されたエッジだけを対象にします。指定しない場合は両方を対象にするため、より厳しい解釈になります。暗黙的なエッジを描画するのは Nx レベルだけです。
ルールを書く前に、知っておくべきことが4つあります。
- レベルが持たないフィールドを指定するセレクターは、何にも一致しません。すべてに一致するわけではありません。
nestjsレベルのpathルールは、どのモジュールも選択しません。NestJS のモジュールグラフは、ファイルパスのないクラス名で構成されているためです。 - フィールドを1つも指定しないセレクターは、スキーマで拒否されます。これは誤記とまったく同じように見えます。また、「すべてのノード」と解釈すると、ルールの対象がワークスペース全体に暗黙のうちに広がってしまいます。
messageは生成された文の代わりではなく、文の後に追加されます。 そのため、ルール名と両方のエンドポイントという「何が起きたか」は常に自動生成されるものとして、「なぜそうなのか」を記述してください。- ルールのないレベルは構築されません。
nestjsルールを宣言すると、すべてのコンテナーがプレビューモードで起動します。また、importsルールを宣言すると、プロジェクトごとにts.Programが作成されます。実際に適用するレベルだけを宣言してください。
すでに満たされているルールを書いてください。 最初から違反状態のルールはゲートではなくバックログです。また、誰も対処できない赤いパイプラインは、人々に無視することを覚えさせてしまいます。候補となるルールをコミットする前に、ワークスペース全体で検証してください。
検出結果が失敗扱いになるプロジェクト
検出結果はプロジェクトに割り当てられ、そのルールが検証するプロジェクトに割り当てられた場合にのみ実行が失敗します。対象となるプロジェクトは、ルールの種類によって決まります。
| 検出結果 | 割り当て先 |
|---|---|
forbid に一致するもの、または allow ルールで許可されないエッジ | エッジのソースを所有するプロジェクトのみ。他のプロジェクトには割り当てられません |
acyclic の循環 | 循環上のノードを所有するすべてのプロジェクト。たとえば A と B をまたぐ循環は、両方のプロジェクトを失敗させます |
| 起動できないコンテナー | コンテナーの起動に失敗したプロジェクト。失敗したクラスが別のプロジェクトに属する場合は、その所有者も示されます |
循環や禁止されたエッジを含むプロジェクトに依存しているだけのプロジェクトは失敗しません。検出結果は「依存先の問題」という注記として表示されます。そのため、ルールはソースプロジェクトを念頭に置いて記述します。変更が必要なのはそのプロジェクトだからです。例外は起動できないコンテナーです。依存先のクラスを評価できないために依存元自身のコンテナーが起動に失敗した場合、依存元も失敗します。実際にそのコンテナーを起動できず、失敗の内容には依存先の所有者が示されるためです。
プロジェクトごとのゲート
Nx ワークスペースでは、@codependix/nx プラグインが、ワークスペースルートを除く、project.json で記述されたすべてのプロジェクトに対して codependix-gate ターゲットを推論します。このターゲットは、そのプロジェクトと依存関係に対して --check boundaries --projects <project> を実行します。package.json だけから Nx が推論するプロジェクトには、project.json が追加されるまでゲートは設定されません。プラグインは nx.json に一度だけ登録します。
{
"plugins": [
{
"plugin": "@codependix/nx",
"options": {
"configurationPath": "configuration/codependix.config.ts",
"gateTargetName": "codependix-gate"
}
}
]
}
configurationPath には、すべてのゲートが読み込む設定を指定する必要があります。これは必須であり、指定しないとオプション名を示すエラーが発生します。また、ワークスペースルートにある codependix.config.ts が自動的に使用されることはありません。ゲートターゲットでは、エグゼキューターの configuration オプションで上書きできます(check または write を選択する Nx 独自の --configuration フラグではありません)。空の値は拒否され、該当するオプション名が示されます。プロジェクトごとに設定する項目はほかにありません。boundaries のルールは、すべてのプロジェクトを同じ方法で判定します。ゲートの実行方法については、codependix-export を参照してください。
ゲートは、プラグインが登録する @swc-node/register のフックを適用した状態でコマンドラインを実行するため、ワークスペースにフック用のパッケージをインストールする必要はありません。ただし、ワークスペースルートにはデコレーターのメタデータを出力する tsconfig.json が必要です。フックは作業ディレクトリからこれを読み込み、NestJS のコンストラクターインジェクションがこの設定に依存するためです。
ゲートはキャッシュされます。プロジェクト独自の codependix.config.* はキャッシュ入力の一つであり、これを編集するとそのゲートが再実行されます。codependix のコマンドライン自体も同様です。ワークスペースのパッケージである場合は、その package.json とソースが入力となり、レジストリからインストールされた場合は、そのインストール済みバージョンが入力となります。ワークスペースルートの tsconfig.json も入力です。これはローダーが読み込むためです。テストファイルは入力に含まれません。そのため、ツールのテストのみを編集しても、そのパッケージ自身と依存するプロジェクト以外のゲートは無効になりませんが、それ以外の編集ではすべてのゲートが再実行されます。プラグインが解決できないパッケージについては、そのパッケージ自身の入力のみが除外され、Nx のロガーが該当するパッケージ名を示して警告します。
projects または tags により、自身のプロジェクト以外も選択するゲートは、コマンドライン、ターゲットのオプション、または名前付き Nx 設定のいずれで指定されていても、キャッシュから再生されません。ゲートが判定するプロジェクトを、その入力がカバーしていないためです。自身のプロジェクトのみを判定するゲートは、通常どおりキャッシュされます。