Turborepo 入門:monorepo のセットアップとキャッシュ設定

スポンサーリンク

Turborepo 入門:monorepo のセットアップとキャッシュ設定

Turborepo は Vercel が開発する monorepo 向けのビルドツールです。複数パッケージを持つリポジトリで、タスク(build・test・lint)をキャッシュし並列実行することでビルド時間を大幅に削減できます。


Turborepo とは

monorepo では複数のパッケージが同じリポジトリに存在します。変更のないパッケージを毎回ビルドし直すのは無駄です。Turborepo はタスクの入出力をハッシュ化してキャッシュし、変更がなければキャッシュ結果を再利用します。

特徴 内容
タスクキャッシュ 入力が同じならキャッシュ結果を返す(リモートキャッシュも可)
並列実行 依存関係を解析して最大並列でタスクを実行
増分ビルド 変更のあったパッケージのみ再ビルド
ゼロランタイム アプリコードへの依存なし。設定ファイルを追加するだけ

前提:npm workspaces の構成

Turborepo は npm / yarn / pnpm の workspaces の上で動きます。以下のような構成を前提にします。

my-monorepo/
├── apps/
│   ├── web/          # Next.js など
│   └── api/          # Express など
├── packages/
│   └── ui/           # 共有コンポーネント
├── package.json       # workspaces 定義
└── turbo.json         # Turborepo 設定

package.json(ルート)に workspaces を定義します。

{
  "name": "my-monorepo",
  "private": true,
  "workspaces": [
    "apps/*",
    "packages/*"
  ]
}

インストール

新規プロジェクトを作る場合

npx create-turbo@latest

対話形式でパッケージマネージャーや構成を選択できます。

既存プロジェクトに追加する場合

npm install turbo --save-dev

インストール後、ルートに turbo.json を作成します。


turbo.json の基本設定

Turborepo v2 以降は tasks キーを使います(v1 の pipeline から変更)。

{
  "$schema": "https://turbo.build/schema.json",
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "dist/**"]
    },
    "test": {
      "dependsOn": ["^build"]
    },
    "lint": {},
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

設定項目の意味

キー 説明
dependsOn: ["^build"] 依存パッケージの build が完了してから実行する
dependsOn: ["build"] 同一パッケージbuild が完了してから実行する
outputs キャッシュに含めるファイル・ディレクトリ
cache: false キャッシュしない(dev など監視系タスクに使う)
persistent: true 長時間実行タスク(サーバー起動など)として扱う

タスクの実行

# すべてのパッケージで build を実行
npx turbo run build

# 複数タスクを同時に実行
npx turbo run build test lint

package.json の scripts に登録すると便利です。

{
  "scripts": {
    "build": "turbo run build",
    "test": "turbo run test",
    "lint": "turbo run lint",
    "dev": "turbo run dev"
  }
}

--filter で対象パッケージを絞る

# apps/web だけビルド
npx turbo run build --filter=web

# packages/ui とその依存パッケージをビルド
npx turbo run build --filter=ui...

# 変更のあったパッケージだけ実行(CI での差分ビルドに便利)
npx turbo run build --filter=[HEAD^1]

キャッシュの仕組み

Turborepo はタスクの「入力」をハッシュ化して保存します。

キャッシュのキーになるもの(デフォルト) - 対象パッケージのソースファイル - package.json の dependencies - turbo.json の設定 - 環境変数(globalEnv / env で指定したもの)

2回目以降に同じ入力でタスクを実行すると、ビルドをスキップしてキャッシュ結果を返します。

$ npx turbo run build
• Packages in scope: web, api, ui
• Running build in 3 packages

 ui:build: cache hit, replaying logs  ← キャッシュヒット
 web:build: cache miss, executing     ← 変更あり・実行
 api:build: cache hit, replaying logs

キャッシュは .turbo/ ディレクトリに保存されます。クリアしたい場合は削除するか --no-cache を付けます。

npx turbo run build --no-cache

.gitignore への追加

.turbo

よく使うコマンドまとめ

コマンド 説明
turbo run build 全パッケージで build を実行
turbo run build test lint 複数タスクを並列実行
turbo run build --filter=web 特定パッケージのみ実行
turbo run build --filter=ui... パッケージとその依存先を実行
turbo run build --filter=[HEAD^1] 変更のあったパッケージのみ実行
turbo run dev --parallel 全パッケージで dev サーバーを起動
turbo run build --no-cache キャッシュを使わず実行
turbo run build --dry-run 実行せず対象タスクを確認

monorepo でのパッケージ管理には npm workspaces が基本になります。npm install の仕組みや package.json の書き方については「npm のバージョン確認コマンドまとめ:npm・npx・package.json のバージョン一覧」も参照してください。