laravel-sailで作るLaravel+Reactの開発環境!(2)

laravel
この記事は約10分で読めます。
記事内に広告が含まれます。

作成する開発環境は「Laravel-sail+React+React-router」を想定している。
LaravelならVueでしょ!という意見もあると思いますが、Reactで作成するほうが大規模開発のような雰囲気があるのと、コンポーネントの考え方のほうが再利用もしやすいと思うからです。

React-routerはReactでページを切り替えて動作するようなサイトを作成するためのモジュールです。
Reactアプリケーションでのルーティングを管理するための人気のあるライブラリです。React Routerを使用すると、SPA(Single Page Application)内で複数のビュー間を切り替えることができます。

私の環境ではWindows11 + WSL2+DockerDesktop環境で作成しています。
そのためWSLでUbuntuの導入までは済んでいるものとします。

laravel sail 環境の作成

curl -s  "https://laravel.build/sample_app?with=mysql,redis" | bash
※withを付けて必要なアプリを指定。付けないと自動でmailpit,meilisearch,mysql,selenium,redisがインストールされます。

Reactの導入

# sailの起動
sail up -d

# nodeのVersion確認
sail node --version

# npmのVersion確認
sail npm --version
スポンサーリンク

Reactの必要モジュールの導入

# Laravelアプリケーションのスターターキット導入
# 詳しくは https://readouble.com/laravel/10.x/ja/starter-kits.html
$ sail composer require laravel/breeze --dev
$ sail php artisan breeze:install react
$ sail npm install -D react-router-dom

# 必要ならtypescripの導入
# $ sail npm install -D typescript @types/react @types/react-dom @types/react-router-dom
# $ sail npx tsc --init --jsx react-jsx

# Sassの導入
$ sail npm install -D sass

初期表示のためのページ作成

Laravelのルーティング設定

routes/web.php

use Illuminate\Support\Facades\Route;

Route::get('{any}', function () {
    return view('index');
})->where('any','.*');

laravelで最初に読み込まれるBradeファイル

resources/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">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>{{ config('app.name', 'Laravel') }}</title>
    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">

    <!-- bootstrap5 -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

    <!-- Scripts -->
    @viteReactRefresh
    @vite(['resources/js/app.css', 'resources/js/app.jsx'])
</head>
<body>
<div id="app"></div>
</body>
</html>

Reactで実行されるルーティングの設定

resources/js/route.jsx

import React from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter, Route, Routes } from 'react-router-dom';

import Home from './Pages/Home';
import Example from './Pages/Example';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/example" element={<Example />} />
      </Routes>
    </BrowserRouter>
  );
}

const container = document.getElementById('app');
const root = createRoot(container);
root.render(<App />);

app.jsxにrouteを追加

resources/js/app.jsx

import './bootstrap';
import '../css/app.css';
import './route';  // この行を追加

import { createRoot } from 'react-dom/client';
import { createInertiaApp } from '@inertiajs/react';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';

const appName = import.meta.env.VITE_APP_NAME || 'Laravel';

createInertiaApp({
    title: (title) => `${title} - ${appName}`,
    resolve: (name) => resolvePageComponent(`./Pages/${name}.jsx`, import.meta.glob('./Pages/**/*.jsx')),
    setup({ el, App, props }) {
        const root = createRoot(el);

        root.render(<App {...props} />);
    },
    progress: {
        color: '#4B5563',
    },
});

ホームページ

resources/js/Pages/Home.jsx

import React from 'react';
import { Link } from 'react-router-dom';
function Home() {
  return (
    <div className="container mt-5">
      <div className="row justify-content-center">
        <div className="col-md-8">
          <div className="card">
            <div className="card-header">Home Component</div>
            <div className="card-body">I'm an home component!</div>
            <Link to={'/example'} className="btn btn-primary">
              Exampleへ遷移
            </Link>
          </div>
        </div>
      </div>
    </div>
  );
}

export default Home;

Exampleページ

resources/js/Pages/Example.jsx

import React from 'react';
import { Link } from 'react-router-dom';
function Example() {
  return (
    <div className="container mt-5">
      <div className="row justify-content-center">
        <div className="col-md-8">
          <div className="card">
            <div className="card-header">Example Component</div>
            <div className="card-body">I'm an home component!</div>
            <Link to={'/'} className="btn btn-primary">
              ホームへ戻る
            </Link>
          </div>
        </div>
      </div>
    </div>
  );
}

export default Example;

実行方法

ターミナルから実行

$ sail npm run dev

http://localhost にアクセスし、動作を確認する

タイトルとURLをコピーしました