Laravel SailとReact+TypeScriptでフロントとバックを分離したSPAを作ろうとして挫折した😇
こんにちはmocchantaiです。
少し前にチャレンジしたけど諦めちゃった時のメモを、成仏させようとブログ化してみました。
もし成功した人がいれば知見を共有してくださると嬉しいです🙇♂️
今回の目標
- バックエンドにLaravel Sail、フロントエンドにReact+TypeScriptを使ってSPAを作る
- フロントとバックのコードをfrontendとbackendディレクトリで分ける
- プロジェクトを1つのGitHubリポジトリで管理する
フロントバックを分離したいモチベーション
webアプリ開発をLaravelから勉強し始めて、その後SPAをReactから勉強しました。
その際、Laravelのresources/js
ディレクトリ内にReactのコードを書いていくことに違和感がありました。
なぜなら、バックエンド=Laravelで、フロントエンド=Reactで作ると言っているのに、ReactのコードがLaravelの中に入っているじゃん!と感じたからです。
どうせなら入れ子構造にせずにフロントとバックエンドのディレクトリを並列して置きたいと考えました。
ディレクトリ構造
ディレクトリはLaravelのデフォルトの構成を元にこんな感じにしました:
Project/
├── backend/
│ ├── app/
│ ├── bootstrap/
│ ├── ...
│ └── vendor/
└── frontend/
├── public/
├── src/
└── ...
プロジェクトのセットアップ手順
-
プロジェクトディレクトリの作成
まず、プロジェクトのルートディレクトリとなるProjectNameを作成します。
mkdir ProjectName cd ProjectName
-
Laravel (Sail)のセットアップ:
ターミナルで以下を実行します。時間がかかるので待ちます。curl -s "https://laravel.build/backend" | bash
最後にPasswordの入力を要求されるので、自分のPCのパスワードを入力します。
Please provide your password so we can make some final adjustments to your application's permissions. Password:
以下の文章が出てきたら完了です。言われている通りにコマンドを打ちましょう。
Thank you! We hope you build something incredible. Dive in with: cd backend && ./vendor/bin/sail up
cd backend && ./vendor/bin/sail up
-
ReactとTypeScriptのセットアップ:
Reactプロジェクトはcreate-react-app
コマンドで簡単に始めることができます。TypeScriptテンプレートを使用することで、型安全な開発環境が初期から利用できます。
先ほどのターミナルではsail upをしているので新しいターミナル上のProjectディレクトリで以下のコマンドを実行します。npx create-react-app frontend --template typescript
cd frontend && npm start
-
frontendディレクトリ内の.gitを削除する
-
frontend
ディレクトリが独自のgitリポジトリとして初期化されている場合があります。これを削除することで、親ディレクトリ(ProjectName
)のgitリポジトリを使ってプロジェクト全体を一元的に管理できるようになります。 -
フロントエンドとバックエンドのコードの変更を一元的に追跡し、プロジェクト全体のバージョン管理を容易にします。以下のコマンドで
frontend
ディレクトリ内の.git
ディレクトリを削除します。rm -rf frontend/.git
-
.gitignore
ファイルはProjectName
ディレクトリのルートに配置し、バックエンドとフロントエンドの両方のファイルを適切に除外できるようにします。
コードを書いていく
Laravelでの簡単なAPIエンドポイントの例
実際にLaravelでAPIエンドポイントを作成する例を以下に示します。この例では、api/hello
というルートを作成し、アクセスすると「Hello, world!」という応答を返します。
-
routes/api.php
にルートを追加します。use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; Route::get('/hello', function (Request $request) { return response()->json(['message' => 'Hello, world!']); });
-
このエンドポイントにアクセスすると、JSON形式でメッセージが返されます。
Laravel APIとReactの連携
-
LaravelでAPIエンドポイントの作成:
-
backend/routes/api.php
にAPIエンドポイントを追加します。
// backend/routes/api.php Route::get('/example', function () { return ['message' => 'Hello from Laravel']; });
-
-
ReactからAPIを呼び出す:
-
frontend/src/Page.tsx
にAPIを呼び出すコードを追加します。
// frontend/src/Page.tsx import React, { useEffect, useState } from 'react'; const Page = () => { const [data, setData] = useState(''); useEffect(() => { fetch('http://localhost:8000/api/example') .then(response => response.json()) .then(data => setData(data.message)); }, []); return <div>{data}</div>; } export default Page;
- ここで
fetch
はLaravelのAPIエンドポイントhttp://localhost:8000/api/example
を呼び出しています。 - Laravel Sailを使用している場合、バックエンドは通常
localhost
の8000ポートで実行されます。
-
CORS問題の解決
Laravel APIをReactアプリから呼び出す際にCORS(Cross-Origin Resource Sharing)問題が発生したので、Laravel側でCORS設定する必要がありました。
LaravelでのCORS設定:
-
まず、
fruitcake/laravel-cors
パッケージをインストールします。このパッケージはCORSヘッダーを簡単に管理するためのものです。composer require fruitcake/laravel-cors
-
次に、
config/cors.php
ファイルで具体的な設定します。例えば、どのパスがCORSのリクエストを受け入れるか、どのオリジンからのアクセスを許可するかなどを定義します。'paths' => ['api/*'], 'allowed_origins' => ['http://localhost:3000'],
ここで挫折
実際にやってみると、特にCORSの設定やDockerの扱いが難しく、思ったより時間がかかりました。結局、設定や環境構築に疲れてしまって挫折してしまいました。
まだまだ学ぶことが多いですが、基礎を固めてから、また挑戦しようと思います。
Discussion