はじめに
本記事では、React、Express、GraphQL、Turborepoを使って、モノレポ環境を構築し、効率的な開発環境を整える方法について解説します。モノレポ構成の利点を活かし、複数のプロジェクトを1つのリポジトリで管理することで、依存関係の管理やビルド時間の短縮、開発のスピードアップが可能になります。Turborepoを活用しフロントエンドとバックエンドを効率的に開発できるセットアップを一緒に学んでいきましょう。
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
さいごに
この記事を通じて、Turborepoを使用したモノレポ構成の基本的なセットアップ方法と、React + ViteのフロントエンドとExpressのバックエンドを統合する方法を学んでいただけたことと思います。このような構成により、複数のアプリケーションを効率よく管理し、ビルドの高速化や依存関係の管理が簡単に行えるようになります。これからモノレポを使った開発環境を整備する際の参考にしていただければ幸いです。Turborepoを使うことで、開発の生産性を大幅に向上させることができますので、ぜひ実際のプロジェクトに取り入れてみてください。
関連する技術ブログ
Webアクセシビリティの完全ガイド:Lighthouse / axe による自動テスト、WCAG基準策定、キーボード操作・スクリーンリーダー対応まで
Webアクセシビリティの課題を解決するための包括的なガイド。Lighthouse / axe を活用した自動テストの設定、WCAGガイドラインに基づく評価基準の整備、キーボード操作やスクリーンリーダー対応の改善、カラーコントラストの最適化、ARIAランドマークの導入、フォームやモーダルの操作性向上まで詳しく解説。定期的なアクセシビリティレポートを活用し、継続的な改善を実現する方法も紹介します。
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
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
Next.jsでのメール認証処理の実装ガイド:トークン検証からログイン画面へのリダイレクト処理までの詳細解説
前回、トークンを生成し認証用のメールを送信する処理を実装しました。今回はその続きの処理を実装していきます。ユーザー登録後、メール認証のためのトークン検証処理を実装し、成功・エラー処理を分けてユーザーに適切なメッセージを表示する方法を紹介します。ReactとNext.jsを活用したシンプルかつ堅牢な認証機能の流れを解説し、実際の動作確認まで行います。
shinagawa-web.com
Next.jsを活用したGitHubとGoogleのOAuth認証実装完全ガイド — スムーズなユーザーログインの実現方法
本記事では、Next.jsを使用してGitHubとGoogleのOAuth認証を実装する方法を詳しく解説します。OAuthの基礎から、実際のコードの書き方、トークン管理、認証後のユーザー管理に至るまで、実践的なステップを順を追ってご紹介します。ユーザーの利便性を高める認証機能をスムーズに実装するための完全ガイドです。
shinagawa-web.com