リポジトリ
ドキュメント
コアコンセプト
タスクのキャッシング

タスクのキャッシング

すべての JavaScript または TypeScript コードベースでは、package.json スクリプト(例:buildtestlint)を実行する必要があります。Turborepo では、これらを **タスク** と呼びます。

Turborepo は、タスクの結果とログをキャッシュできるため、遅いタスクの速度が大幅に向上します。

キャッシュがない場合

コードベースの各タスクには、**入力** と **出力** があります。

  • build タスクには、ソースファイルが入力として含まれ、stderrstdout へのログ、およびバンドルされたファイルが出力として含まれる場合があります。
  • lint または test タスクには、ソースファイルが入力として含まれ、stdoutstderr へのログが出力として含まれる場合があります。

turbo run build を使用して Turborepo で build タスクを実行するとします。

  1. Turborepo は、**タスクへの入力を評価し、ハッシュに変換します**(例:78awdk123)。

  2. ローカルファイルシステムのキャッシュに一致するキャッシュアーティファクト(例:./node_modules/.cache/turbo/78awdk123.tar.zst)を確認します。

  3. Turborepoが計算されたハッシュと一致するアーティファクトを見つけられない場合、Turborepoはタスクを実行します。

  4. タスクが正常に完了すると、Turborepoは指定されたすべての出力(ファイルとログを含む)を、ハッシュによってアドレス指定された新しいキャッシュアーティファクトに保存します。

Turborepoは、ハッシュを作成する際に、依存関係グラフ、依存するタスク、ソースファイル、環境変数などを考慮に入れています。

キャッシュヒット

入力内容を変更せずにタスクを再度実行するとします。

  1. 入力内容が変更されていないため(例:78awdk123)、ハッシュは同じになります

  2. Turborepoは、一致するハッシュを持つキャッシュアーティファクト(例:./node_modules/.cache/turbo/78awdk123.tar.zst)を見つけます。

  3. タスクを実行する代わりに、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"]
    }
  }
}
{
  "$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はタスクの出力をキャッシュするだけでなく、ターミナル出力(つまり、stdoutstderrの組み合わせ)を(<package>/.turbo/run-<command>.log)に記録します。turboがキャッシュされたタスクに遭遇すると、あたかも再度発生したかのように、しかし瞬時に、パッケージ名が少し暗く表示されて出力が再生されます。

ハッシング

ここまでで、おそらくturboが特定のタスクについてキャッシュヒットとキャッシュミスのどちらを構成するかについて疑問に思っていることでしょう。良い質問です!

まず、turboは、コードベースの現在のグローバル状態のハッシュを作成します。これには以下のようなものがあります。

  • globalDependenciesに指定されたglobパターンに一致する全てのファイルの内容のハッシュ値
  • globalEnvにリストされている環境変数の値
  • turbo.jsonpackage.json、および任意のlockファイルからの選択情報
  • その他!

その後、特定のワークスペースのタスクに関連する要素を追加します。

  • ワークスペースフォルダ内のバージョン管理下にある全てのファイルの内容のハッシュ値(設定されている場合、inputs globに一致するファイル)
  • pipelineで指定された設定済みのoutputs
  • インストール済みの全てのdependenciesdevDependencies、およびoptionalDependenciesの解決済みのバージョンセット
  • ワークスペースタスクの名前
  • pipeline.<task>.envリストで指定された、ソート済みの環境変数のキーと値のペアのリスト。
  • その他!

turboが実行時に特定のワークスペースのタスクに遭遇すると、一致するハッシュ値についてキャッシュ(ローカルとリモートの両方)を確認します。一致する場合、そのタスクの実行をスキップし、キャッシュされた出力を適切な場所に移動またはダウンロードし、以前に記録されたログを即座に再生します。ローカルとリモートのどちらのキャッシュにも計算されたハッシュ値と一致するものが存在しない場合、turboはローカルでタスクを実行し、指定されたoutputsをキャッシュします。

特定のタスクのハッシュ値は、実行時に環境変数TURBO_HASHとしてタスクで使用できます。この値は、出力へのスタンプやDockerfileへのタグ付けなどに役立ちます。