LoginSignup
31
18

Laravel × React + TypeScript で SPA の開発環境を構築(Laravel Sail を利用)

Last updated at Posted at 2022-08-27

Laravel Sail を用いて、Laravel9 × React18 の SPA の開発環境を構築したので紹介させていただきます。

Laravel × React で SPA を作成する記事は少なくないですが、Sail のデフォルトの設定を変更する方法( Docker の知識なしで変更できる範囲で)や、Sass の導入方法なども併せてまとめているので、読んでいただけると嬉しいです。

2022年6月から、新たに Laravel のインストールした際のデフォルトのビルド・ツールとして、vite(ヴィート)が採用されました。本記事でも、Laravel Mix ではなく、vite を使用しています。

Laravel Sail とは

 Laravel Sail は、Docker の経験を必要とせず、PHP、MySQL、Redis などを用いた Laravel アプリケーションの開発環境を Docker 上で構築することができるツールです。
(ただし、MySQL の代わりに MongoDB を使用したい場合など、Sail 側で用意されていない設定に変更する場合には Docker の知識が必要になることがあります。)

ローカル環境

  • macOS Monterey v12.3 (MacBook Air M1 2020)
  • Docker v20.10.8

Docker Desktopのインストール

Laravel Sail を用いた開発環境の構築には、Docker が必要です。
OS 環境によってインストールの方法が異なりますが、macOS か Windows の場合、Docker Desktop をインストールすることで簡単に Docker を利用できます。
以下のサイトなどを参考にしてください。

Dockerについて学びたい方は以下の記事が参考になるかもしれません。Docker の基礎概念と用語の解説から、docker-compose.yml を用いた複数コンテナの定義・実行まで詳しくまとめられており、基礎固めができると思います。

Laravel の開発環境の作成

Laravel の開発環境を構築していきます。

ターミナル開き、任意のディレクトリに移動してください。
以下のコマンドで Laravel の開発環境が構築できます。

ターミナル
curl -s "https://laravel.build/example-spa?with=mysql,mailhog" | bash
  • ここではアプリケーション名を『 example-spa 』にしていますが、お好きな名前に変えていただいても問題ありません。

  • 『 ?with=mysql,mailpit 』をつけること、MySQL と MailHog を利用できます。( ?with= をつけない場合、mysql、redis、meilisearch、mailpit、selenium が設定されます。)

  • MySQL の代わりに PostgreSQL を使いたい場合は、『 mysql 』を『 pgsql 』に変更してください。
    ?with= 以降に設定できるサービスについて詳しく知りたい方は公式サイト(installation choosing-your-sail-services)を参考にしてください。

Laravel アプリケーションが作成されると、Password を求められるので パソコンの Password を入力します。

ターミナル
Application ready! Build something amazing.
Sail scaffolding installed successfully.

Please provide your password so we can make some final adjustments to your application's permissions.

Password:

Password 入力後、以下の文章が表示されると思いますので、

ターミナル
Thank you! We hope you build something incredible. 
Dive in with: cd example-spa && ./vendor/bin/sail up

指示通りにタイプし、Sail を起動します。

ターミナル
cd example-spa && ./vendor/bin/sail up

Web ブラウザで http:// localhost にアクセスし、Laravel と書かれたページが表示されるか確認します。
[Ctrl] + [C]キー で Sail を一度停止します。

Laravel Sail で構築したアプリケーションでは、Sail コマンドを用いて開発していきますが、毎回、./vendor/bin/sail を打つのは面倒なので、シェルエイリアスを設定します。
詳しくは、公式サイト(sail configuring-a-shell-alias)を参考にしてください。

以下のようにシェルエイリアスを設定することで、./vendor/bin/sailsail に変更しても問題なく起動します。

ターミナル
alias sail='[ -f sail ] && bash sail || bash vendor/bin/sail'
sail up -d

sail up の後に -d をつけていますが、バックグラウンドで Sail を起動するためのオプションで、新たにターミナルを開かなくても他のコマンドを入力することができます。

Reactの導入(TypeScript対応)

それでは、React の開発環境の導入を行います。

今回は、React の開発環境を Laravel の開発環境内に構築します。
具体的には、 resources ディレクトリ内に ts ディレクトリを作成し、その中で、Laravel のインストールと同時にインストールされた node や npm 、npx を利用しながら、React の開発を行います。

構築した Laravel の開発環境に node や npm、npxがインストールされているか確認します。

ターミナル
sail node --version
# v16.17.0
sail npm --version
# 8.18.0
sail npx --version
# 8.18.0

React に必要なモジュールのインストール

以下のコマンドで、package.json ファイル内に記述されたパッケージ( Laravel で Vite を使うのに必要なものなど)を一括でインストールされます。
node_modulesディレクトリ と package-lock.json も同時に作成されます。

ターミナル
sail npm install

React に必要なモジュールのインストールします。

ターミナル
sail npm install -D react react-dom @types/react @types/react-dom
sail npm install -D @vitejs/plugin-react

# Reactでルーティングを実装したい場合は、以下のパッケージもインストール
# sail npm install -D react-router-dom
# sail npm install -D @types/react-router-dom

typescriptを導入

ターミナル
sail npm install -D typescript

sail npx tsc --init --jsx react-jsx

tsconfig.json がルートディレクトリに作成されます。

viteの設定

vite.config.js を編集します。

vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react'; // <- 追加

export default defineConfig({
    plugins: [
        laravel({
            // input: ['resources/css/app.css', 'resources/js/app.js'],
            refresh: true,

            // typescriptとsassが使えるように変更
            input: [
                'resources/sass/app.scss', 
                'resources/ts/index.tsx'
            ],
        }),
        react(), // <- 追加
    ],
});

input内で、TSXファイルと、Sassファイルのエントリーポイントを指定します。
create-react-appでReactの環境を構築した場合、index.tsx がアプリケーションへのエントリポイント(パス)になるので、それに合わせていますが、任意のファイル名に変更も問題ありません。

refresh: true は、以下のような効果があるみたいです。

refreshオプションがtrueの場合、resources/views/**、app/View/Components/**、routes/**のファイルを保存すると、npm run dev実行中に、ブラウザがページのフル再ロードを行うようになります。
参考:Laravel 和訳翻訳ドキュメント - vite

react()を追加することで Fast Refresh などの機能を取り込めます。詳しくは@vitejs/plugin-reactを参照してください。

index.blade.php の作成

views ディレクトリ内に index.blade.php を作成します。

welcome.blade.php は不要なので削除してください。

resouces/views/index.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>sample-api</title>

        {{-- react に変更があったとき自動で --}}
        @viteReactRefresh
        @vite(['resources/sass/app.scss', 'resources/ts/index.tsx'])

    </head>

    <body class="antialiased">
        <div id="app"></div>
    </body>
</html>

@vite() 内に TSXファイル と、 Sassファイル のエントリーポイントを設定します。
@viteReactRefresh@vite の前に呼び出す必要があります。

index.tsxの作成

resourcesディレクトリ内に ts ディレクトリを追加し、その中に index.tsx を作成します。

resources/ts/index.ts
import React from 'react';
import { createRoot } from 'react-dom/client';

const container = document.getElementById('app');
const root = createRoot(container!); // createRoot(container!) if you use TypeScript

root.render(
  // <React.StrictMode>
    <div className="text-red">
        Hello World
    </div>
// </React.StrictMode>,
);

web.php の編集

welcomeindex に変更します。

routes/web.php
// Route::get('/', function () {
//     return view('welcome');
// });
Route::get('/', function () {
    return view('index');
});

Sass の導入

sass のパッケージをインストールします。

ターミナル
sail npm install -D sass

resources/css/app.cssresources/sass/app.scss に変更します。

resources/sass/app.scss
.text-red {
    color: red;
}

React と Sass の動作確認

ターミナル
sail npm run dev

http://localhost にアクセスし、赤文字で Hello World と表示されれば、React と Sass は問題なく動作しています。

Laravel と React の連携

最後に、Laravel と React の連携を行います。

App.tsxの作成

resources/ts ディレクトリ配下に App.tsx を作成します。

resources/ts/App.ts
import React, { useEffect } from 'react';
import axios from 'axios';

const App: React.FC = () => {
    useEffect(()=>{
        const fetchFromLaravel = async () => {
            const res  = await axios.get(`/api/hoge`);
            alert(res.data.hoge)
        };
        fetchFromLaravel();
    }, [])

    return (
        <div className="App"></div>
    );
}

export default App;

index.tsxの編集

resources/ts/index.ts
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App'; // <- 追加

const container = document.getElementById('app');
const root = createRoot(container!); // createRoot(container!) if you use TypeScript

root.render(
  // <React.StrictMode>
    <div className="text-red">
        {/* Hello World */}
        <App /> {/* <- 追加 */}
    </div>
// </React.StrictMode>,
);

api.phpの編集

routes/api.php
Route::get('/hoge', function (Request $request) {
    return response()->json(
        [
            'hoge' => 'Hello from Laravel'
        ]
    );
});

http:// localhost にアクセスし、Alert で Hello from Laravel と表示されれば、Laravel と React の連携は完了です。

[Ctrl] + [C]キー で vite を停止します。

Sail も停止します。

ターミナル
sail down

終わりに

今回は、Laravel と React を連携するための最低限のセットアップにとどまり、認証機能の導入やデータベースの利用などをしていません。
Laravel では、SPA 用の認証として Laravel Sanctum が用意されているなど、Web API 開発のための機能が多く準備されているので公式ドキュメントなどを参考してください。

31
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
18