メインコンテンツへスキップ
見出し画像

フロントとバックを最速で繋ぐ!Bun Workspaceで実現するストレスフリーなモノレポ開発

    こんにちは!Accel-Hack(アクセルハック) 開発チームです。

    社内アシスタント「Airi」の開発において、私たちはバックエンドとフロントエンドを1つのリポジトリで管理する「モノレポ(Monorepo)」構成を採用しています。

    以前のVol.4では、AIエージェント(Antigravity等)と人間が協働して開発スピードを最大化するための「機能駆動(Feature-First)アーキテクチャ」についてご紹介しました。

    そして機能駆動アーキテクチャをシステム基盤として支えているのが、今回のテーマである Bun Workspace です。

    バックエンド(Cloudflare Workers / Hono)と、フロントエンド(React / Vite)の2つを別々のリポジトリで管理していると、APIの型定義を共有するだけでも一苦労です。
    パッケージの依存関係もバラバラになり、デプロイやローカル起動のたびにそれぞれのディレクトリで作業をしなければなりません。

    「よし、それならモノレポにしよう!」と決めたのはいいものの、Node.jsベースのツール(npm、yarn、pnpmなど)でモノレポ(Workspaces)を組もうとすると、設定ファイルの複雑さや node_modules の肥大化、そして何より npm install の遅さにストレスを感じることに。

    そこで私たちが採用したのが、超高速JavaScriptランタイムである Bun です。


    1. 導入:なぜモノレポなのか? そしてなぜ Bun なのか?

    バックエンドとフロントエンドを別々のリポジトリで管理していると、常に「情報の二重管理」が発生します。

    例えば、バックエンドで定義した型情報をフロントエンドで利用するためには、手動でコピーするか、あるいはプライベートなnpmレジストリを用意して共有するなどの手間がかかります。

    また、機能を追加・修正するたびに2つのリポジトリでコミットやプルリクエストを作成し、それぞれでデプロイ手順を踏む必要があります。

    この摩擦を解消するのが「モノレポ」構成です。
    コードベースを1つに統合することで、型定義は単にファイルをインポートするだけで共有可能になり、機能の追加も1つのコミット、1つのプルリクエストで完結します。

    しかし、従来のパッケージマネージャー(npmやpnpmなど)でモノレポを構築しようとすると、以下のような課題に直面しがちです。

    1. 設定の複雑さ: 依存パッケージの解決やシンボリックリンクの設定など、設定ファイルが複雑化しやすい。

    2. インストールの遅さ: ワークスペース全体のパッケージをインストールするのに時間がかかる。

    3. node_modules の肥大化: 重複するパッケージが多くなり、ストレージを圧迫する。

    これらの課題を一挙に解決してくれたのが Bun でした。Bunは実行速度の速さが注目されがちですが、パッケージマネージャーとしても極めて優秀で、シンプルなWorkspace機能が最初から統合されています。


    2. Bun Workspace によるシンプルなモノレポ構造

    Airiのコードベースでは、以下のようなディレクトリ構造でモノレポを管理しています。

    画像

    ルートディレクトリにバックエンドのコード(src/ 配下)と設定ファイル(wrangler.toml)を置き、フロントエンドは独立した frontend/ ディレクトリ配下にカプセル化しています。

    この構成でモノレポ化するために行った設定は、ルートの package.json に以下の2行を追加しただけです。

    {
      "name": "airi",
      "private": true,
      "workspaces": ["frontend"]
    }

    これだけで、Bunは frontend ディレクトリをサブプロジェクト(ワークスペース)として自動的に認識してくれます。
    あとはルートディレクトリで以下のコマンドを一発実行するだけです。

    bun install

    実行すると、フロントエンド(frontend/)とバックエンド(ルート)の全依存関係が一瞬で解決され、ルートの bun.lock 一つで一括管理されます。
    複数のディレクトリを行ったり来たりしてパッケージを個別にインストールしていた時間は不要になり、数秒でセットアップが完了します。


    3. 「Only Bun!」を徹底するための防御的設定

    モノレポの運用でよくあるトラブルが、「チームメンバー(あるいはAIエージェント)が誤って npm install や pnpm install を実行してしまい、リポジトリ内に package-lock.json や pnpm-lock.yaml が混入して依存関係が壊れる」という問題です。

    特にAIペアプログラミングを行っていると、AIは一般的なやり方に引っ張られて npm コマンドを提案したり実行したりしがちです。

    そこで、Airiのプロジェクトでは「Bun以外のパッケージマネージャーの使用をシステム的に禁止する」ための防御的設計を取り入れました。

    具体的には、ルートの package.json に以下のような設定を記述しています。

    {
      "scripts": {
        "preinstall": "node -e \"if (!process.env.npm_config_user_agent.includes('bun')) { console.error('\\x1b[31mError: Only Bun is allowed in this project. Please run \\'bun install\\'.\\x1b[0m'); process.exit(1); }\""
      }
    }

    この "preinstall" スクリプトが、インストール実行時に動く npm_config_user_agent 環境変数をチェックし、bun という文字列が含まれていない場合はエラーを出して即座にプロセスを終了(process.exit(1))させます。

    これにより、うっかり npm install や yarn install を叩いてしまっても、以下のように赤文字でエラーメッセージを表示して実行をブロックしてくれます。

    Error: Only Bun is allowed in this project. Please run 'bun install'.
    

    さらに、engines フィールドや "packageManager": "bun@1.3.6" を定義しておくことで、チームメンバー間での Bun のバージョン統一も図っています。


    4. モノレポ全体のタスクをルートからシームレスに制御する

    モノレポにした際、フロントエンドとバックエンドの起動やビルドを別々のターミナルで実行する手間が発生します。
    これも開発効率を下げる一因です。

    Bun Workspace では、bun run --cwd <workspace-name> <script> コマンドを使うことで、ルートディレクトリにいながらサブプロジェクトのタスクを実行できます。

    Airiでは、ルートの package.json に以下のようなショートカットスクリプトを定義しています。

    {
      "scripts": {
        "dev": "bun run --hot index.ts",
        "build:fe": "bun run --cwd frontend build",
        "build:prod": "tsc --noEmit && bun run build:fe"
      }
    }
    • バックエンドの開発起動: ルートで単に bun run dev を実行するだけです。--hot オプションにより、コード変更時に超高速でホットリロードされます。

    • フロントエンドのビルド: bun run build:fe を実行すると、--cwd frontend オプションにより frontend ディレクトリ配下のビルドスクリプトが呼び出されます。

    • プロダクションビルド: bun run build:prod でバックエンドの型チェック(tsc --noEmit)とフロントエンドのビルドをまとめて実行します。

    これにより、開発者はバックエンドとフロントエンドの境界線を意識することなく、ルートディレクトリに留まったまま、思考を妨げずに作業を続けることができます。


    5. 学びと成果:Bun Workspace がもたらした「思考のスピード」での開発

    Bun Workspace を導入した結果、私たちの開発効率(DX)は劇的に向上しました。

    主な成果は以下の通りです。

    1. インストールの待ち時間が「ほぼゼロ」に: 新しいパッケージを追加する際も、数秒で完了するため、開発のリズムが途切れません。

    2. 依存関係のクリーンな分離: バックエンドとフロントエンドは同一リポジトリでありながら、package.json は別々に管理されているため、フロントエンド(React/Tailwind)の巨大な依存関係がバックエンド(Workers)の軽量な実行環境に混入することはありません。

    3. AIとのスムーズな協働: preinstall スクリプトでガードしたことにより、AIエージェントが間違ったコマンドを実行して環境を壊す心配がなくなり、安心して作業を自律的に任せられるようになりました。

    バックエンドとフロントエンドが密結合しながらも、お互いの領域を侵さない。モノレポと Bun Workspace の組み合わせは、まさに現代の爆速開発において最強のソリューションだと感じています。


    6. おわりに

    いかがでしたでしょうか?
    Airiの開発では、インフラのエッジ環境(Cloudflare)と、開発環境・実行環境(Bun)を組み合わせることで、初期段階から「圧倒的なスピード」を意識した基盤構築を行ってきました。

    次回は、この環境で動く、エッジ向けの軽量Webフレームワーク 「Vol. 6: エッジ環境への挑戦「Hono」」 についてご紹介します!

    Cloudflare Workers上で動作する超高速な API サーバーをどのように構築したのか、その裏側をお届けしますので、ぜひお楽しみに!


    この記事は以下の体制で作成されました。

    • ドラフト作成・執筆: Airi (社内AIアシスタント)

    • アイデア出し・レビュー: CTO

    • デザイン: 事務スタッフ

    Accel-Hackでは、テクノロジーを駆使して世の中の課題を解決していく仲間を募集しています。
    私たちの取り組みに少しでも興味を持っていただけたら、ぜひ採用ページや会社サイトも覗いてみてくださいね。


    あなたへのおすすめ