はじめに
本記事では、Next.js AppRouter を用いたプロジェクトで Turborepo を活用し、モノレポ構成を効率的に運用する手法を紹介します。
インクリメンタルビルドやキャッシングを活かしてビルド時間を削減し、開発チーム全体の生産性を高めることを目指しています。
想定読者
- 職業 / 役職:Webエンジニア(フロントエンド中心)
- スキルレベル:React や Next.js に慣れており、中級者レベル。モノレポ運用に興味があるが、本格導入は未経験。
-
課題 / ニーズ:
- 複数の Next.js プロジェクトをまとめて管理し、共通コンポーネントや設定を再利用したい
- アプリのビルド時間を短縮し、CI/CD での開発効率を上げたい
- Next.js の新機能(AppRouterなど)を活かしつつ、スケーラブルなプロジェクト体制に移行したい
1. Turborepo とは何か
Turborepo の概要
Turborepo は Vercel が提供するモノレポビルドシステムです。
複数のアプリやパッケージを1つのリポジトリ(モノレポ)で管理する際に、そのビルド・テスト・リントなどのタスクを効率的に実行できるよう設計されています。
主な特徴
-
インクリメンタルビルド & キャッシング
変更のあったプロジェクト部分のみ再ビルドし、既存の成果物をキャッシュから再利用します。 -
並列実行
ビルド・テスト・リント等のタスクを並列に走らせるため、時間を大幅に短縮可能。 -
リモートキャッシング
CI/CD 環境やチームメンバー間でキャッシュを共有し、ビルド時間をさらに圧縮できます。 -
ゼロ設定でもすぐに使える
初期状態から直感的に使い始められ、必要に応じて柔軟にカスタマイズ可能。
参考:より詳細なドキュメントは公式サイト(Turborepo Docs)を参照してください。
2. モノレポと Turborepo を使うメリット
モノレポの基本構造
モノレポは、単一のリポジトリで複数のアプリケーションやライブラリを管理する開発スタイルです。Turborepo では、以下のようなディレクトリ構成を推奨しています。
/
├─ apps/
│ ├─ web/ // Next.js (AppRouter)
│ └─ admin/ // 別の Next.js アプリなど
└─ packages/
├─ ui/ // 共通UIコンポーネント
├─ eslint-config-custom/
└─ tsconfig/
-
apps/
独立して動作するアプリケーション。
例:複数の Next.js アプリや microservices など。 -
packages/
共有コンポーネント、共通ライブラリ、設定ファイルなどをまとめる場所。
Turborepo の利点
-
効率的な依存関係管理
ワークスペース機能により、アプリ間で共有するライブラリを一元管理。バージョン管理が楽になります。 -
タスクの統一実行
ルートのpackage.json
やturbo.json
で定義したスクリプトを、turbo run dev
などで一括実行できる。 -
キャッシュの活用
一度実行したビルドやテストの結果をキャッシュして再利用。変更がない部分は処理をスキップするため超高速。
参考:Zenn などのコミュニティで、Turborepo を使ったモノレポ構築方法が多く解説されていますので、あわせて参照すると理解が深まります。
3. Next.js AppRouter と Turborepo の連携方法
AppRouter は、サーバーコンポーネントや新しいファイル構造など、多くの点で従来の Pages Router とは異なります。
ここでは、Next.js AppRouter を複数プロジェクトで運用しながら、Turborepo で効率化する手順をステップごとに見ていきましょう。
ステップ 1: Turborepo プロジェクトの作成
まずは、モノレポのベースとなるプロジェクトを作成します。
npx create-turbo@latest
このコマンドを実行すると、対話形式でいくつか質問が表示されるので、以下のように選択するとよいでしょう。
- ディレクトリ構成:
apps/
とpackages/
を作成 - パッケージマネージャー:
pnpm
(高速で依存関係管理がしやすい)
プロジェクトが作成されると、apps/
と packages/
ディレクトリが用意された状態になるので、そこに必要なアプリや共通ライブラリを追加していきます。
ステップ 2: Next.js アプリの追加
apps/
ディレクトリに、AppRouter 対応の Next.js アプリを新規作成します。
cd apps
npx create-next-app@latest my-app
メモ:最新の CLI では
--experimental-app
の代わりに--app
オプション等に変わっていることがあります。
バージョンによってコマンドが異なる場合は、最新のドキュメントを確認してください。
これで、apps/my-app/
以下に AppRouter 対応の Next.js プロジェクトが生成されます。
ステップ 3: 共有設定の整備
1. TypeScript 設定
packages/tsconfig
のようなディレクトリを作成し、複数のアプリ間で共有したい設定を tsconfig.json
として切り出します。
各アプリ側の tsconfig.json
では次のように継承させます。
{
"extends": "tsconfig/nextjs.json",
"compilerOptions": {
// プロジェクト固有の設定
}
}
2. ESLint 設定
同様に、ESLint 設定も packages/eslint-config-custom/
などに格納します。
各アプリで以下のように拡張設定として利用します。
// .eslintrc.js
module.exports = {
extends: ["eslint-config-custom"], // packages/eslint-config-customを参照
// ...
};
3. 共通コンポーネント
アプリ間で使い回すコンポーネントを packages/ui
ディレクトリに配置し、そこに Button
などを実装しておきます。
各アプリからは次のようにインポート可能です。
import { Button } from "ui";
export default function Page() {
return <Button>Click Me</Button>;
}
ヒント:
package.json
でワークスペースエイリアスを設定しておくと、"ui": "workspace:*"
のように指定して依存関係を管理できます。
ステップ 4: スクリプトの統一管理
ルートの package.json
に、よく使うタスクをまとめて定義します。
{
"scripts": {
"dev": "turbo run dev",
"build": "turbo run build",
"lint": "turbo run lint"
}
}
これにより、各アプリに個別で dev
や build
スクリプトを指定していても、ルートでまとめて実行できるようになります。
ステップ 5: タスク実行とキャッシュ活用
Turborepo は turbo.json
に記載されたパイプライン定義に従ってタスクを実行します。
例えば、以下のように設定することでビルド成果物をキャッシュし、変更のない部分をスキップ可能です。
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"outputs": [".next/**", "!.next/cache/**"]
},
"dev": {
"cache": false,
"persistent": true
},
"lint": {}
}
}
-
outputs:キャッシュしたい出力フォルダを指定(
.next/
など) -
cache:
false
に設定するとキャッシュを無効化。開発時にリアルタイムでビルドを確認したい場合に便利。 -
persistent:
true
の場合、監視モードなどでプロセスを継続。
フィルターオプション:
turbo run dev --filter=my-app
などとすることで、特定アプリだけタスクを実行することもできます。
4. 具体的な導入手順まとめ
-
ステップ 1 :
npx create-turbo@latest
でプロジェクト作成 -
ステップ 2 :
apps/
配下でcreate-next-app --experimental-app
を実行し、Next.js AppRouter プロジェクトを追加 -
ステップ 3 : 共有設定(tsconfig、ESLint など)を
packages/
にまとめて管理 -
ステップ 4 : ルートの
package.json
に各種スクリプトを定義し、turbo run dev
などで一括実行 -
ステップ 5 :
turbo.json
でキャッシュやパイプラインを細かく指定し、ビルド時間を大幅に短縮
5. 応用トピック / Tips
CI/CD 環境でのリモートキャッシング
Turborepo の リモートキャッシング 機能を使うと、CI/CD パイプラインでもビルド成果物を再利用でき、チームメンバーの開発マシンともキャッシュを共有可能になります。
たとえば、Vercel や GitHub Actions などを組み合わせ、キャッシュを共有設定すると、複数ブランチを切り替えてもビルド時間を短縮でき、プルリクエストの検証がスピーディになります。
既存プロジェクトのモノレポ化
すでに運用中の Next.js プロジェクトをモノレポに統合する場合は、まず個別リポジトリで動いているアプリを apps/
に移し、共通化できる設定やライブラリを packages/
に分割していきましょう。
初期段階で ESLint や tsconfig などを整備しておくと移行しやすくなります。
小規模プロジェクトでも有効か?
数ページだけの Next.js プロジェクトなど、小規模ならば「必須」というわけではありません。
しかし、複数プロジェクトやコンポーネントをまたいだ管理が必要になるなら、早めの段階からモノレポを導入しておくと、後で拡張しやすいです。
まとめ
本記事では、Next.js AppRouter と Turborepo を組み合わせてモノレポを構築する方法を解説しました。
Turborepo を活用すれば、1 人でも複数のプロジェクトを効率的に開発でき、チーム開発ではビルド時間や設定管理のストレスを大幅に削減できます。
もしあなたが Next.js や React を中心としたプロジェクトを複数抱えているなら、今すぐにでも導入を検討してみてはいかがでしょうか?
参考
-
Turborepo 公式ドキュメント
最新の設定オプションやリモートキャッシングの解説が充実 -
Next.js 公式ドキュメント
AppRouter を含む新機能の詳細をチェック -
Zenn などのコミュニティ記事
実際のプロジェクトでの導入事例や Tips が多数