はじめに
本記事では、React、Express、GraphQL、Turborepoを使って、モノレポ環境を構築し、効率的な開発環境を整える方法について解説します。モノレポ構成の利点を活かし、複数のプロジェクトを1つのリポジトリで管理することで、依存関係の管理やビルド時間の短縮、開発のスピードアップが可能になります。Turborepoを活用しフロントエンドとバックエンドを効率的に開発できるセットアップを一緒に学んでいきましょう。
今回のゴール
フロントエンドであるReactとバックエンドであるExpressを1つのリポジトリにセットアップし、turborepo
を使ってまとめて起動できるようにします。
その後、ReactからExpressにアクセスできることを確認します。
ディレクトリ構成が初見では複雑に見えますので詳しい解説も載せています。
.
├── apps
│ ├── backend
│ │ ├── src
│ │ │ └── index.ts
│ │ ├── package.json
│ │ └── tsconfig.json
│ └── frontend
│ ├── dist
│ │ ├── assets
│ │ │ ├── index-D5Y6grW-.js
│ │ │ └── index-kQJbKSsj.css
│ │ ├── index.html
│ │ └── vite.svg
│ ├── public
│ │ └── vite.svg
│ ├── src
│ │ ├── assets
│ │ │ └── react.svg
│ │ ├── App.tsx
│ │ ├── main.tsx
│ │ └── vite-env.d.ts
│ ├── .gitignore
│ ├── README.md
│ ├── eslint.config.js
│ ├── index.html
│ ├── package.json
│ ├── tsconfig.app.json
│ ├── tsconfig.json
│ ├── tsconfig.node.json
│ └── vite.config.ts
├── package-lock.json
├── package.json
└── turbo.json
Turborepoとは
Turborepo(ターボレポ)は、モノレポ(monorepo)構成を管理するためのツールで、主にJavaScriptやTypeScriptのプロジェクトに利用されます。モノレポとは、複数のプロジェクトやパッケージを一つのリポジトリ内で管理するアプローチです。Turborepoは、このようなモノレポを効率的に扱うためのツールです。
Turborepoの主な特徴
-
ビルドパイプラインの高速化: Turborepoは、依存関係の管理を効率化するため、インクリメンタルビルドをサポートします。変更された部分のみを再ビルドすることで、ビルド時間を短縮し、開発を加速します。
-
キャッシュ機能: ビルド結果をキャッシュすることで、同じ処理を何度も行わずに済みます。これにより、CI/CDやローカル開発環境でのビルドが高速化されます。
-
依存関係の管理: モノレポ内の複数のパッケージ間での依存関係を効率よく管理できます。Turborepoは、タスクやスクリプトが依存するパッケージ間で自動的に適切な順序で処理を実行します。
-
分散型タスク実行: 複数のパッケージが存在する場合でも、Turborepoは並列にタスクを実行して、開発のスピードを向上させます。
-
簡単な設定: Turborepoは、turbo.jsonという設定ファイルを用いてプロジェクトの設定を簡単に管理できます。また、npmやpnpm、yarnなどのパッケージマネージャーと統合されており、標準的なツールチェインと共に動作します。
-
CI/CDサポート: Turborepoは、CI/CDパイプラインを効率的に設定できるようサポートします。変更のあった部分だけをビルドし、無駄な作業を省けます。
セットアップ
まずは全体のプロジェクトのセットアップから始めます。
mkdir Documents/workspace/react-express-graphql-turborepo
cd Documents/workspace/react-express-graphql-turborepo
npm init -y
Turborepo
を使えるようインストールします。
npm install turbo -D
次にTurborepo
の設定を行います。
タスクという形でビルドや開発モードでの起動などの設定ができます。
{
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"dev": {
"cache": false,
"persistent": true
}
}
}
dev
で起動する時は基本的に長時間実行されるもので"persistent": true
を入れることでreact
とexpress
の双方が他タスクに影響を与えて中断されないようにしています。
次にルート直下のpackage.jsonの修正をします。
{
"name": "react-express-graphql-turborepo",
+ "workspaces": ["apps/*", "packages/*"],
"version": "1.0.0",
"description": "",
- "main": "index.js",
+ "packageManager": "npm@10.9.2",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"turbo": "^2.4.0"
}
}
package.jsonのworkspacesは、モノレポ(monorepo)を構築するための設定です。モノレポとは、複数のパッケージやアプリケーションを単一のリポジトリ内で管理するアプローチです。
workspacesを使用すると、異なるパッケージ(アプリケーションやライブラリ)を同じリポジトリ内で効率的に管理でき、依存関係の共有やインストールの高速化、開発の効率化ができます。
以上でルート直下での初期設定は終了となります。
フロントエンド(React + Vite)の作成
ここから個別のアプリケーションの設定となります。
まずはフロントエンドから設定してきます。
mkdir apps
cd apps
npm create vite@latest frontend
{
- "name": "frontend",
+ "name": "@react-express-graphql-turborepo/frontend",
"private": true,
スコープ付きパッケージの設定をします。
今回の記事ではまだあまり重要ではありませんが一旦設定しておきます。
ViteとReactの必要なファイルをダウンロードできたのでパッケージをインストールします。
cd apps/frontend
npm install
インストールが終わったら念のため起動し動作確認をしておきます。
npm run dev
下記のように表示され、http://localhost:5173/
にアクセスできればOKです。
VITE v6.1.0 ready in 319 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h + enter to show help
以上でVite + Reactによるフロントエンドの設定は終了です。
今回はモノレポ構成についてがメインとなるためViteやReactについての記載は最小限にしていますが、これらのツールについて詳しく知りたい方はこちらの記事もご参考ください。
バックエンド(Experss)の作成
次にバックエンドとしてExpressの設定を行います。
まずはパッケージのインストールを行います。
mkdir apps/backend && cd apps/backend
npm init -y
npm i express cors dotenv
npm i -D typescript ts-node @types/node @types/express @types/cors
その後、スコープ付きパッケージの設定、tsconfig.json
の設定を行います。
{
- "name": "backend",
+ "name": "@react-express-graphql-turborepo/backend",
"version": "1.0.0",
{
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"strict": true,
"module": "CommonJS",
"target": "ES6",
"esModuleInterop": true
}
}
Express
を動かせる環境ができましたら実際に起動するファイルを作成します。
import express from "express";
import cors from "cors";
const app = express();
const PORT = process.env.PORT || 4000;
app.use(cors());
app.use(express.json());
app.get("/", (req, res) => {
res.send("Hello from Express!");
});
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
まずはhttps://localhost:4000
でアクセスすると、Hello from Express!
と返ってくるようにしました。
ファイルが作成できましたら、package.json
で起動する処理を定義します。
- "main": "index.js",
+ "main": "index.ts",
"scripts": {
+ "dev": "ts-node src/index.ts",
"test": "echo \"Error: no test specified\" && exit 1"
},
念のためExpress
が起動できるか確認します。
npm run dev
Server is running on http://localhost:4000
起動できましたら、curl
でレスポンスを確認します。
curl http://localhost:4000
Hello from Express!
以上でExperss
のセットアップは終了となります。
こちらについてもExpressの記載は最小限にしていますが、詳しく知りたい方はこちらの記事もご参考ください。
フロントエンドからバックエンドにアクセス
fetch
モジュールを使って先ほど返ってきたHello from Express!
をブラウザで表示させます。
import { useEffect, useState } from "react";
function App() {
const [message, setMessage] = useState("");
useEffect(() => {
fetch("http://localhost:4000")
.then((res) => res.text())
.then((data) => setMessage(data));
}, []);
return (
<div>
<h1>React + Express</h1>
<p>API Response: {message}</p>
</div>
);
}
export default App;
初期設定のCSSが残って影響を与えるので一旦削除します。
rm apps/frontend/src/index.css
rm apps/frontend/src/App.css
またcssを読み込んでいるファイルも修正しておきます。
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
- import './index.css'
import App from './App.tsx'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
</StrictMode>,
)
一通り設定ができましたのでReactとExpressをTurborepoから起動します。
ルート直下で下記コマンドを実行します。
npm run dev
起動でき、APIのレスポンスがブラウザに表示されることを確認します。
ディレクトリ構成について
基本的にはapps
配下がメインとなります。
今回はfrontend
, backend
という2つのディレクトリを用意してそれぞれ管理する形としました。
tree -I node_modules -I .git -I .turbo --dirsfirst -a
.
├── apps
│ ├── backend
│ │ ├── src
│ │ │ └── index.ts
│ │ ├── package.json
│ │ └── tsconfig.json
│ └── frontend
│ ├── dist
│ │ ├── assets
│ │ │ ├── index-D5Y6grW-.js
│ │ │ └── index-kQJbKSsj.css
│ │ ├── index.html
│ │ └── vite.svg
│ ├── public
│ │ └── vite.svg
│ ├── src
│ │ ├── assets
│ │ │ └── react.svg
│ │ ├── App.tsx
│ │ ├── main.tsx
│ │ └── vite-env.d.ts
│ ├── .gitignore
│ ├── README.md
│ ├── eslint.config.js
│ ├── index.html
│ ├── package.json
│ ├── tsconfig.app.json
│ ├── tsconfig.json
│ ├── tsconfig.node.json
│ └── vite.config.ts
├── package-lock.json
├── package.json
└── turbo.json
トップレベルのディレクトリ
.
├── package-lock.json
├── package.json
├── turbo.json
- package.json
- モノレポ全体のルート package.json
- apps/backend や apps/frontend の依存関係を統合管理する
- workspace の設定
- package-lock.json
- インストールされた依存関係のバージョンが固定されるファイル
- npm install を実行すると自動生成される
- turbo.json
- Turborepo の設定ファイル
- どのパッケージを
apps
に含めるか、どのスクリプトを並列/キャッシュ実行するかを定義
アプリケーションのディレクトリ (apps/)
├── apps
│ ├── backend
│ └── frontend
- apps/ 内に backend (Express) と frontend (React + Vite) が分かれている
- モノレポの標準的なディレクトリ構造
backend
とfrontend
をそれぞれ 独立したプロジェクトとして管理
バックエンド (apps/backend/)
│ ├── backend
│ │ ├── src
│ │ │ └── index.ts
│ │ ├── package.json
│ │ └── tsconfig.json
- src/index.ts
- Express のエントリーポイント
- サーバーを起動するメインファイル
- package.json
- バックエンドの 依存関係やスクリプト を管理
フロントエンド (apps/frontend/)
│ └── frontend
│ ├── dist
│ │ ├── assets
│ │ │ ├── index-D5Y6grW-.js
│ │ │ └── index-kQJbKSsj.css
│ │ ├── index.html
│ │ └── vite.svg
│ ├── public
│ │ └── vite.svg
│ ├── src
│ │ ├── assets
│ │ │ └── react.svg
│ │ ├── App.tsx
│ │ ├── main.tsx
│ │ └── vite-env.d.ts
│ ├── .gitignore
│ ├── README.md
│ ├── eslint.config.js
│ ├── index.html
│ ├── package.json
│ ├── tsconfig.app.json
│ ├── tsconfig.json
│ ├── tsconfig.node.json
│ └── vite.config.ts
- dist/
- Vite でビルドされたファイルが格納される
assets/
に JS, CSS, 画像などのビルド成果物 が入る
- public/
- 静的ファイル を格納
vite.svg
は Vite のデフォルトアイコンpublic/
のファイルはdist/
にコピーされる
- src/
- フロントエンドのソースコード
- vite.config.ts
Vite
の設定ファイルReact
プラグインやalias
設定を記述
さいごに
この記事を通じて、Turborepoを使用したモノレポ構成の基本的なセットアップ方法と、React + ViteのフロントエンドとExpressのバックエンドを統合する方法を学んでいただけたことと思います。このような構成により、複数のアプリケーションを効率よく管理し、ビルドの高速化や依存関係の管理が簡単に行えるようになります。これからモノレポを使った開発環境を整備する際の参考にしていただければ幸いです。Turborepoを使うことで、開発の生産性を大幅に向上させることができますので、ぜひ実際のプロジェクトに取り入れてみてください。
関連する技術ブログ
Webアクセシビリティの完全ガイド:Lighthouse / axe による自動テスト、WCAG基準策定、キーボード操作・スクリーンリーダー対応まで
Webアクセシビリティの課題を解決するための包括的なガイド。Lighthouse / axe を活用した自動テストの設定、WCAGガイドラインに基づく評価基準の整備、キーボード操作やスクリーンリーダー対応の改善、カラーコントラストの最適化、ARIAランドマークの導入、フォームやモーダルの操作性向上まで詳しく解説。定期的なアクセシビリティレポートを活用し、継続的な改善を実現する方法も紹介します。
shinagawa-web.com
チャットアプリ(画像・PDF送信、ビデオ通話機能付き)
お客様固有の要件を除き一般的なチャットアプリに求められる最低限の機能を実装しデモアプリとしてご紹介いたします。
shinagawa-web.com
React × Tailwind CSS × Emotionで実践するコンポーネント設計ガイド:デザインシステム・状態管理・再利用性の最適解
React、Tailwind CSS、Emotion、Storybook、Figma、Next.jsを活用したコンポーネント設計のベストプラクティスを紹介。デザインシステムに基づく命名規則、適切な状態管理、再利用性を高める抽象化、アクセシビリティ対応、スタイルガイドラインの整備、テーマ設定、バージョン管理、ドキュメント作成まで、モダンフロントエンド開発に欠かせない知識を徹底解説します。
shinagawa-web.com
Chakra UI・ShadCN・Material UIを活用したデザインシステムの構築と運用
デザインシステムの要件定義から適用ガイドラインの策定、UIコンポーネントの設計・実装、レスポンシブ対応、アクセシビリティ強化まで、幅広い観点で解説。Chakra UI・ShadCN・Material UIなどのUIフレームワークを活用しながら、カラーパレットやタイポグラフィの統一、コードスタイルの整備、開発者・デザイナー向けのドキュメント作成、プロトタイピング、ユーザビリティ向上のためのテスト戦略までを包括的に取り上げます。
shinagawa-web.com
管理ダッシュボード機能(グラフ表示、データ取り込み)
一般的な家計簿アプリとして求められる最低限の機能を実装しデモアプリとしてご紹介いたします。
shinagawa-web.com
Mock Service Worker (MSW) を使ったAPIモックとテストの効率化
MSW(Mock Service Worker)を使用して、フロントエンド開発やテスト環境でのAPIモックを効率的に行う方法を解説します。Mock Service Workerの基本的な使い方から、Jestテストでの活用方法、さらにテストを簡単にするための設定手順を紹介します。
shinagawa-web.com
Next.jsとAuth.jsで認証機能を実装するチュートリアル
Next.jsでアプリケーションを作る時に必要となる認証機能をどのように実装するかをご紹介する記事となります。アカウント登録から始まり、ログイン、ログアウト、ページごとのアクセス制御、OAuth、二要素認証、パスワードリセットなど認証に関連する様々な機能をコードベースでご紹介します。
shinagawa-web.com
Next.jsでのメール認証処理の実装ガイド:アカウント登録からトークン検証まで
Next.jsを活用したメール認証の実装方法を解説。アカウント登録時のトークン発行から、Sendgridを使ったメール送信処理まで、具体的な手順を紹介します。
shinagawa-web.com
弊社の技術支援サービス
無駄なコストを削減し、投資対効果を最大化する
クラウド費用の高騰、不要なSaaSの乱立、開発工数の増加――これらの課題に悩んでいませんか?本サービスでは、クラウドコストの最適化、開発効率向上、技術選定の最適化 を通じて、単なるコスト削減ではなく、ROIを最大化する最適解 をご提案します。
shinagawa-web.com
最新技術の導入・検証を支援するPoCサービス
Remix、React Server Components、TypeScript移行、クラウドサービス比較、マイクロサービス、サーバーレス、デザインシステムなど、最新技術のPoC(概念実証)を通じて、最適な技術選定と導入を支援します。貴社の開発課題に合わせた検証・実装で、ビジネスの成長を加速させます。
shinagawa-web.com
開発生産性を最大化するための支援サービス
開発チームの生産性向上、コードの品質管理、インフラの最適化まで、様々な側面からサポートします。コードベースのリファクタリングから、テスト自動化、オンボーディング強化まで、プロジェクトの成功に必要なすべての支援を提供。御社の開発現場が効率的に機能するように、技術的な障害を取り除き、スムーズな開発を実現します。
shinagawa-web.com
開発品質向上支援 – 効率的で安定したプロダクトを実現
フロントエンドからバックエンド、データベースまで、開発プロセス全体を最適化し、安定したプロダクト作りをサポートします。コードレビューの仕組み、型定義の強化、E2Eテスト環境の構築など、開発の各ステップにおけるベストプラクティスを導入することで、より効率的でバグの少ない、そしてユーザー満足度の高いサービス提供を支援します。
shinagawa-web.com
Webアプリのセキュリティ強化支援
Webアプリの脆弱性対策からインフラのセキュリティ強化まで、包括的なセキュリティ支援を提供。OWASP Top 10対策、JWT認証の最適化、APIのアクセス制御、依存パッケージの監査、セキュアコーディングの標準化など、実践的なアプローチで開発現場の安全性を向上させます。
shinagawa-web.com
目次
お問い合わせ