既存のモノレポにTurborepoを追加する
ワークスペースの設定
turbo
は、単一のモノレポパッケージ内で複数のパッケージを管理する方法であるワークスペースの上に構築されています。Turborepo は、すべてのパッケージマネージャーのワークスペース実装と互換性があります。Turborepo ワークスペースの管理の詳細については、ワークスペースのドキュメントを参照してください。
ワークスペースは自由に構成できますが、一般的なフォルダー構造の例としては、アプリケーションを /apps
フォルダーに、パッケージを /packages
フォルダーに保持することです。これらのフォルダーの構成は、パッケージマネージャーごとに異なります。
モノレポのルートにある package.json
ファイルで workspaces
を指定します
{
"workspaces": ["packages/*", "apps/*"]
}
ワークスペースを設定したら、パッケージマネージャーの install
コマンドを再実行します。
turbo
をインストール
turbo
をグローバルにインストールします。
npm install turbo --global
インストールの詳細については、Turborepoのインストールを参照してください。
turbo.json
を作成
モノレポのルートに、turbo.json
という名前の空のファイルを作成します。ここにTurborepoの設定を保持します。
{
"$schema": "https://turbo.dokyumento.jp/schema.json"
}
pipeline
を作成
モノレポのタスク依存グラフを定義するには、モノレポのルートにある turbo.json
構成ファイルで pipeline
キーを使用します。turbo
はこの構成を解釈して、各ワークスペースで定義された package.json
スクリプトの出力を最適にスケジュール、実行、およびキャッシュします。
pipeline
オブジェクト内の各キーは、turbo run
で実行できる package.json
スクリプトの名前です。内部の dependsOn
キーで依存関係を指定したり、キャッシングに関連するその他のオプションを指定できます。パイプラインの設定の詳細については、Pipelines
のドキュメントを参照してください。
package.json
の scripts
リストに指定されたスクリプトが定義されていないワークスペースは、turbo
によって無視されます。
{
"$schema": "https://turbo.dokyumento.jp/schema.json",
"pipeline": {
"build": {
// A package's `build` script depends on that package's
// dependencies and devDependencies
// `build` tasks being completed first
// (the `^` symbol signifies `upstream`).
"dependsOn": ["^build"],
// note: output globs are relative to each package's `package.json`
// (and not the monorepo root)
"outputs": [".next/**", "!.next/cache/**"]
},
"deploy": {
// A package's `deploy` script depends on the `build`,
// `test`, and `lint` scripts of the same package
// being completed. It also has no filesystem outputs.
"dependsOn": ["build", "test", "lint"]
},
"test": {
// A package's `test` script depends on that package's
// own `build` script being completed first.
"dependsOn": ["build"],
// A package's `test` script should only be rerun when
// either a `.tsx` or `.ts` file has changed in `src` or `test` folders.
"inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts", "test/**/*.tsx"]
},
// A package's `lint` script has no dependencies and
// can be run whenever. It also has no filesystem outputs.
"lint": {},
"dev": {
"cache": false,
"persistent": true
}
}
}
特定のパッケージの実行順序の大まかな基準は、dependsOn
キーに基づいています。
build
は、アップストリームの依存関係がbuild
コマンドを実行した後に実行されます。test
は、パッケージ内で *自身の*build
コマンドが終了し、ファイルシステムへの出力がない(ログのみ)場合に実行されます。lint
は、アップストリームの依存関係がないため、任意の順序で実行されます。deploy
は、*自身の*build
、test
、およびlint
コマンドが終了した後に実行されます。
実行後、パイプライン全体を実行できます。
npx turbo run deploy
turbo
は、マシンのリソースの使用を最適化するために、各タスクの実行をスケジュールします。
.gitignore
を編集します。
.turbo
を .gitignore
ファイルに追加します。CLI は、これらのフォルダーをログや特定のタスクの出力に使用します。
+ .turbo
キャッシュしたいタスクの成果物、ファイル、フォルダーも、.gitignore
に含めるようにしてください。
+ build/**
+ dist/**
+ .next/**
npm クライアントの install
コマンドを再実行して、構成を確認します。
モノレポをビルドします。
turbo build
モノレポの設定によっては、一部の成果物がすでに適切にキャッシュされている可能性があります。次のセクションでは、turbo
の仕組み、scope
の仕組み、そしてその後キャッシュを機能させる方法を示します。
リモートキャッシングの設定
Turborepo の速度の主な鍵🔑は、それが怠惰かつ効率的であることです。可能な限り最小限の作業を行い、以前に完了した作業をやり直さないようにします。
現在、Turborepo はローカルファイルシステムにタスクをキャッシュしています(いわば「シングルプレイヤーモード」です)。ただし、チームメイトや CI が行った計算作業を活用する方法(いわば「協力型マルチプレイヤーモード」)があったらどうでしょうか?マシン間で単一のキャッシュをテレポートして共有する方法があったらどうでしょうか?Turborepo キャッシュの「Dropbox」のようなものです。
リモートキャッシングが登場しました。
Turborepo は、リモートキャッシングとして知られる手法を使用して、マシン間でキャッシュされた成果物を共有し、速度をさらに向上させることができます。
リモートキャッシングは Turborepo の強力な機能ですが、強力な機能には大きな責任が伴います。最初に正しくキャッシュされていることを確認し、環境変数の処理を再確認してください。また、Turborepo はログを成果物として扱うため、コンソールに出力している内容に注意してください。
ローカル開発でのリモートキャッシングの使用
Turborepo は、デフォルトのリモートキャッシングプロバイダーとして Vercel (新しいタブで開きます) を使用します。ローカルの turborepo をリモートキャッシュにリンクする場合は、Turborepo CLI を Vercel アカウントで認証できます。
turbo login
次に、turborepo をリモートキャッシュにリンクします。
turbo link
有効にしたら、現在キャッシュしているパッケージまたはアプリケーションに変更を加え、turbo run
でタスクを実行します。キャッシュされた成果物は、ローカルとリモートキャッシュに保存されます。これが機能したことを確認するには、ローカルの Turborepo キャッシュを削除します。
rm -rf ./node_modules/.cache/turbo
同じビルドをもう一度実行します。正常に機能していれば、turbo
はタスクをローカルで実行するのではなく、リモートキャッシュからログと成果物の両方をダウンロードして、再生します。
注: SSO が有効な Vercel チームに接続する場合は、npx turbo login
の引数としてチームのスラッグを指定する必要があります。
turbo login --sso-team=<team-slug>
次のステップ
Turborepo の起動と実行が完了しましたが、まだやるべきことがいくつかあります。