タスクのキャッシング
すべての JavaScript または TypeScript コードベースでは、package.json
スクリプト(例:build
、test
、lint
)を実行する必要があります。Turborepo では、これらを **タスク** と呼びます。
Turborepo は、タスクの結果とログをキャッシュできるため、遅いタスクの速度が大幅に向上します。
キャッシュがない場合
コードベースの各タスクには、**入力** と **出力** があります。
build
タスクには、ソースファイルが入力として含まれ、stderr
とstdout
へのログ、およびバンドルされたファイルが出力として含まれる場合があります。lint
またはtest
タスクには、ソースファイルが入力として含まれ、stdout
とstderr
へのログが出力として含まれる場合があります。
turbo run build
を使用して Turborepo で build
タスクを実行するとします。
-
Turborepo は、**タスクへの入力を評価し、ハッシュに変換します**(例:
78awdk123
)。 -
ローカルファイルシステムのキャッシュに一致するキャッシュアーティファクト(例:
./node_modules/.cache/turbo/78awdk123.tar.zst
)を確認します。 -
Turborepoが計算されたハッシュと一致するアーティファクトを見つけられない場合、Turborepoはタスクを実行します。
-
タスクが正常に完了すると、Turborepoは指定されたすべての出力(ファイルとログを含む)を、ハッシュによってアドレス指定された新しいキャッシュアーティファクトに保存します。
Turborepoは、ハッシュを作成する際に、依存関係グラフ、依存するタスク、ソースファイル、環境変数などを考慮に入れています。
キャッシュヒット
入力内容を変更せずにタスクを再度実行するとします。
-
入力内容が変更されていないため(例:
78awdk123
)、ハッシュは同じになります。 -
Turborepoは、一致するハッシュを持つキャッシュアーティファクト(例:
./node_modules/.cache/turbo/78awdk123.tar.zst
)を見つけます。 -
タスクを実行する代わりに、Turborepoは出力を再生します。保存されたログを
stdout
に出力し、保存された出力ファイルをファイルシステム内のそれぞれの位置に復元します。
キャッシュからのファイルとログの復元はほぼ瞬時に行われます。これにより、ビルド時間を数分または数時間から数秒または数ミリ秒に短縮できます。具体的な結果は、コードベースの依存関係グラフの形状と粒度によって異なりますが、ほとんどのチームは、Turborepoのキャッシングによって、全体の月間ビルド時間を約40~85%削減できることを発見しています。
キャッシングの無効化
一部の環境では、キャッシュ出力を書き込まない場合があります。キャッシュ書き込みを無効にするには、任意のコマンドに--no-cache
を追加します。たとえば、これによりdev
(およびそれがdependsOn
するすべてのタスク)がすべてのワークスペースで実行されますが、出力はキャッシュされません。
turbo run dev --no-cache
--no-cache
はキャッシュ書き込みを無効化しますが、キャッシュ読み込みは無効化しません。キャッシュ読み込みを無効にするには、--force
フラグを使用します。
pipeline.<task>.cache
設定をfalse
に設定することで、特定のタスクのキャッシュへの書き込みをスキップするように設定することもできます。
{
"$schema": "https://turbo.dokyumento.jp/schema.json",
"pipeline": {
"dev": {
"cache": false,
"persistent": true
}
}
}
キャッシュの強制上書き
逆に、キャッシュの読み取りを無効にして、以前にキャッシュされたタスクのturbo
による再実行を強制する場合は、--force
フラグを追加します。
# Run `build` npm script in all workspaces ignoring the cache.
turbo run build --force
--force
はキャッシュ読み込みを無効化しますが、キャッシュ書き込みは無効化しません。キャッシュ書き込みを無効にするには、--no-cache
フラグを使用します。
Node.jsバージョンの処理
Node.jsのバージョンを考慮するには、package.jsonのengines
キー (opens in a new tab)を使用します。Turborepoはpackage.json
への変更を検出し、フィールドが更新されるとキャッシュをヒットしません。
プラットフォームとその他の任意のハッシュ寄与者の処理
高度なユースケースでは、オペレーティングシステム(OS)、アーキテクチャ、またはその他の外部要因をハッシュに含める必要がある場合があります。これは、4つの簡単な手順で行うことができます。
1. 任意のファイルをディスクに書き込む
まず、関心のあるハッシュ寄与者を考慮したスクリプトを作成します。たとえば、プラットフォームとアーキテクチャを確認し、その詳細をファイル(turbo-cache-key.json
)に書き込むNode.jsスクリプトを次に示します。
#!/usr/bin/env node
const { writeFileSync } = require('fs');
const { join } = require('path');
const { platform, arch } = process;
const file = "turbo-cache-key.json";
const str = JSON.stringify({ platform, arch });
console.log(`Generating cache key: ${str}`);
writeFileSync(file, str);
2. ファイルを.gitignoreに追加する
このファイルは環境に依存するため、ソースコントロールにコミットしたくありません。.gitignore
に追加します。
// .gitignore
+ turbo-cache-key.json
3. ファイルをハッシュに追加する
次に、turbo
がタスク入力に追加することでファイル認識できるようにします。これを行うには2つの方法があります。
- 特定のタスクの場合:タスクの
inputs
配列にファイルを指定します。
{
"$schema": "https://turbo.dokyumento.jp/schema.json",
"pipelines": {
"build-for-platforms": {
"dependsOn": ["^build"],
"inputs": ["$TURBO_DEFAULT$", "turbo-cache-key.json"]
}
}
}
- すべてのタスクの場合:ファイルを
globalDependencies
に追加します。
{
"$schema": "https://turbo.dokyumento.jp/schema.json",
"globalDependencies": ["turbo-cache-key.json"],
"pipelines": {
...
}
}
4. turbo
の実行前にファイルを生成する
最後に、turbo
を実行する前にスクリプトを実行する必要があります。例:
{
"scripts": {
"build-for-platforms": "node ./scripts/create-turbo-cache-key.js && turbo run build"
}
}
turbo run build
は、build
タスクのハッシュを計算する際に、turbo-cache-key.json
の内容を考慮に入れます。
ログ
turbo
はタスクの出力をキャッシュするだけでなく、ターミナル出力(つまり、stdout
とstderr
の組み合わせ)を(<package>/.turbo/run-<command>.log
)に記録します。turbo
がキャッシュされたタスクに遭遇すると、あたかも再度発生したかのように、しかし瞬時に、パッケージ名が少し暗く表示されて出力が再生されます。
ハッシング
ここまでで、おそらくturbo
が特定のタスクについてキャッシュヒットとキャッシュミスのどちらを構成するかについて疑問に思っていることでしょう。良い質問です!
まず、turbo
は、コードベースの現在のグローバル状態のハッシュを作成します。これには以下のようなものがあります。
globalDependencies
に指定されたglobパターンに一致する全てのファイルの内容のハッシュ値globalEnv
にリストされている環境変数の値turbo.json
、package.json
、および任意のlockファイルからの選択情報- その他!
その後、特定のワークスペースのタスクに関連する要素を追加します。
- ワークスペースフォルダ内のバージョン管理下にある全てのファイルの内容のハッシュ値(設定されている場合、
inputs
globに一致するファイル) pipeline
で指定された設定済みのoutputs
- インストール済みの全ての
dependencies
、devDependencies
、およびoptionalDependencies
の解決済みのバージョンセット - ワークスペースタスクの名前
pipeline.<task>.env
リストで指定された、ソート済みの環境変数のキーと値のペアのリスト。- その他!
turbo
が実行時に特定のワークスペースのタスクに遭遇すると、一致するハッシュ値についてキャッシュ(ローカルとリモートの両方)を確認します。一致する場合、そのタスクの実行をスキップし、キャッシュされた出力を適切な場所に移動またはダウンロードし、以前に記録されたログを即座に再生します。ローカルとリモートのどちらのキャッシュにも計算されたハッシュ値と一致するものが存在しない場合、turbo
はローカルでタスクを実行し、指定されたoutputs
をキャッシュします。
特定のタスクのハッシュ値は、実行時に環境変数TURBO_HASH
としてタスクで使用できます。この値は、出力へのスタンプやDockerfileへのタグ付けなどに役立ちます。