Turborepo + pnpm: Monorepo管理をより円滑にする「強力な」コンビ

Development tutorial - IT technology blog
Development tutorial - IT technology blog

バラバラになった数十ものリポジトリの管理に頭を抱えたことはありませんか?

想像してみてください。ウェブアプリ、管理画面、APIシステムの3つのプロジェクトを抱えているとします。共通のユーティリティ関数(utils)やUIコンポーネントを修正するたびに、3つのIDEウィンドウを開き、コードをコピー&ペーストして、それぞれを苦労して更新しなければなりません。これは非常に時間の無駄です。Monorepo(モノレポ)は、まさにその痛みを解消するために生まれました。

実用的に言えば、Monorepoはすべてのプロジェクトとパッケージを1つの「家」にまとめます。しかし、単にフォルダをまとめるだけで、調整するツールがなければ、すぐに混乱状態に陥ってしまいます。そこで、ライブラリ管理のための pnpm と、実行速度を向上させるための Turborepo が必要になります。

5分でMonorepoを構築する

理屈を並べるよりも、まずはサンプルプロジェクトで手を動かしてみましょう。ターミナルを開いて次のように入力します。

npx create-turbo@latest

パッケージマネージャーを尋ねられたら、pnpm を選択してください。インストール後、プロジェクトの構造は次のようになります。

  • apps/: Web、ダッシュボード、ブログなどのメインプロダクトを配置。
  • packages/: UI、Config、Utilsなどの共通ライブラリの保管場所。
  • turbo.json: Turborepoにプロジェクトの運用方法を教えるロードマップ。

pnpm dev コマンドを実行するだけで、Turborepoはすべてのアプリケーションの開発モードを同時に自動起動します。非常にプロフェッショナルで洗練された感覚を味わえるでしょう。

なぜ pnpm と Turborepo は「最強のペア」なのか?

pnpm – 数十GBのディスク容量を節約

npmやyarnは、肥大化した node_modules フォルダを作成しがちです。pnpmの場合、「コンテンツ・アドレサブル・ストア」の仕組みにより、各ライブラリのコピーはディスク上に1つだけ保存されます。実際、私が5つのReactプロジェクトを含むリポジトリをnpmからpnpmに移行した際、ストレージ容量は2GBから400MB強にまで削減されました。Monorepoにおいて、pnpmの Workspaces 機能は、コードをnpmレジストリにプッシュすることなく子プロジェクト同士を連携させるのに役立ちます。

Turborepo – 終わった作業を二度と繰り返さない

pnpmが「資産」を管理するなら、Turborepoは製造責任者です。その最大の武器は Caching(キャッシュ機能) です。アプリケーションAのコードに変更がない場合、Turborepoは前回のビルド結果をわずか数ミリ秒で取得します。

5人の開発者が参加する実際のプロジェクトでこのワークフローを統合したところ、驚くべき結果が得られました。CI/CDシステムのビルド時間が、インテリジェントなキャッシュメカニズムのおかげで10分から2分足らずに短縮されたのです。もともと変更されていないコードのために、無意味に待機し続ける必要はもうありません。

コード共有:1箇所の修正ですべてを更新

最も素晴らしいのは、Webと管理画面の両方で共通のUIパッケージを作成できることです。例えば、カスタムボタンを含む packages/ui があるとします。これを apps/web で使用するには、package.json ファイルで次のように宣言するだけです。

{
  "dependencies": {
    "@repo/ui": "workspace:*"
  }
}

workspace:* という記号は、pnpmに対して「このリポジトリ内にある最新バージョンを優先的に取得せよ」という合図になります。

柔軟なパイプライン設定

turbo.json ファイルを通じて、Turborepoに作業の順序を教える必要があります。

{
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "dist/**"]
    },
    "lint": {},
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

^ 記号には非常に論理的な意味があります。すべての依存関係(dependencies)のビルドが完了してから、自身のビルドを開始するという意味です。手動で介入しなくても、システムは常に正しい順序で実行されます。

Monorepoを円滑に管理するための3つの秘訣

以下は、私が得た「実戦での」経験です。

  1. Filter(フィルター)を使用する: Webアプリだけを修正したのにリポジトリ全体をビルドするのはやめましょう。時間の節約のために、pnpm build --filter=web コマンドを使用してください。
  2. パッケージを細分化する: 巨大な utils の塊を作るのではなく、utils-authutils-api などに分割しましょう。これにより、キャッシュがより正確に機能し、認証コードを修正しただけでシステムがAPI部分まで再ビルドすることを防げます。
  3. Remote Cachingを有効にする: チームで作業する場合は、Vercel Remote Cacheを使用しましょう。同僚がすでに自分のマシンでビルドを完了していれば、あなたのマシンはその結果をダウンロードするだけで済みます。これはまさにチームの生産性における革命です。

Monorepoへの移行は、最初の数日間は少し戸惑うかもしれません。しかし、一度このスピード感と整理された状態に慣れてしまえば、以前のバラバラな管理方法に戻りたいとは思わなくなるでしょう。最適で持続可能なシステムを構築できることを願っています!

Share: