タスクグラフ
前のセクションでは、Turborepoがturbo.json
を使用して、タスクがどのように相互に関連しているかを表現する方法について説明しました。これらの関係はタスク間の依存関係と考えることができますが、より正式な名前があります。それがタスクグラフです。
Turborepoは、有向非巡回グラフ(DAG) (新しいタブで開きます)と呼ばれるデータ構造を使用して、リポジトリとそのタスクを理解します。グラフは「ノード」と「エッジ」で構成されています。タスクグラフでは、ノードはタスクであり、エッジはタスク間の依存関係です。*有向*グラフは、各ノードを接続するエッジに方向があることを示しているため、タスクAがタスクBを指している場合、タスクAはタスクBに依存していると言えます。エッジの方向は、どのタスクがどのタスクに依存しているかによって異なります。
たとえば、2つのパッケージ@repo/ui
と@repo/utils
に依存するアプリケーションapps/web
を含むモノレポがあるとします。
my-monorepo
└─ apps
└─ web
└─ packages
└─ ui
└─ utils
そして、^build
に依存するbuild
タスクがあるとします。
{
"pipeline": {
"build": {
"dependsOn": ["^build"]
}
}
}
Turborepoはこのようにタスクグラフを構築します。
中継ノード
タスクグラフを構築する際の課題は、ネストされた依存関係の処理です。たとえば、core
パッケージに依存するui
パッケージに依存するdocs
アプリケーションがモノレポにあるとします。
my-monorepo
└─ apps
└─ docs
└─ packages
└─ ui
└─ core
docs
アプリと core
パッケージにそれぞれ build
タスクがあると仮定しましょう。ただし、ui
パッケージには build
タスクがありません。また、上記と同じ方法で build
タスクを設定する turbo.json
があり、"dependsOn": ["^build"]
となっています。turbo run build
を実行すると、何が起こると予想されますか?
Turborepo は、このタスクグラフを構築します。
このグラフは、一連のステップとして考えることができます。
docs
アプリはui
のみに依存しています。ui
パッケージにはビルドスクリプトが**ありません**。ui
パッケージの*依存関係*にはbuild
スクリプトがあるため、タスクグラフにはそれらが含まれます。
Turborepo は、このシナリオでは ui
パッケージをトランジットノードと呼びます。これは、独自の build
スクリプトがないためです。build
スクリプトがないため、Turborepo は ui
パッケージに対して何も実行しませんが、依存関係を含める目的で、グラフの一部として残ります。
グラフにトランジットノードを含めなかった場合はどうなるでしょうか?
上記の例では、タスクグラフに ui
ノード(とその依存関係)を含めています。これは、Turborepo が期待どおりにキャッシュミスすることを確認するための重要な違いです。
デフォルトでトランジットノードを**除外**する場合、core
パッケージのソースコードの変更は、turbo run build
に対する docs
アプリのキャッシュを無効化せず、以前の core
パッケージの反復からの古いコードを使用します。
エントリポイントとしてのトランジットノード
docs/
パッケージが build
タスクを実装していない場合はどうなるでしょうか?この場合、何が起こると予想されますか?ui
パッケージと core
パッケージは、それでもビルドタスクを実行する必要がありますか?ここで*何か*が起こるべきでしょうか?
Turborepo のメンタルモデルは、タスクグラフ内のすべてのノードが同じであるというものです。言い換えれば、トランジットノードは、グラフ内のどこに表示されるかに関係なく、グラフに含まれます。このモデルは、予期しない結果をもたらす可能性があります。たとえば、build
タスクを ^test
に依存するように設定したとしましょう。
{
"pipeline": {
"build": {
"dependsOn": ["^test"]
}
}
}
モノレポに多数のアプリと多数のパッケージがあるとします。すべてのパッケージに test
タスクがありますが、1 つのアプリにのみ build
タスクがあります。Turborepo のメンタルモデルでは、turbo run build
を実行すると、アプリが build
を実装していなくても、依存関係であるすべてのパッケージの test
タスクがグラフに表示されます。