LaravelにReact + TypeScript の開発環境を構築

# この記事の目的
- LaravelとReactでTodoアプリを作成したときの備忘録
- Reactのインストールからルーティング設定について
- Laravel9を利用しています
- React+TypeScriptとScssを追加しています。

# 前提として
Laravel9のバージョン9.2からデフォルトのビルドツールがWebpack(Laravel Mix)からViteに変更になっています。
Viteを利用することでフロントエンド開発のスピードをあげることができるので、デフォルトのビルドツールViteを使用してReactをインストールしていきます。
[Viteとは](https://qiita.com/inagacky/items/ad424821653067c99253)


# Laravel + Vite + React環境構築について
#### フローとしては下記のような形で行なっていきます
- ①Viteの編集
- ②必要なモジュールのインストール
- ③index.tsx作成
- ④scssファイル作成
- ⑤packge.jsonの確認
- ⑥画面に表示してみる
## ①Viteの編集
Laravel9のプロジェクトを作成するとプロジェクト配下に`vite.config.js`ができているかと思います。
今回はTypeScriptを使用するので拡張子を下記のように編集する
```
vite.config.js → vite.config.ts
```
#### 拡張子を編集したら内容を下記のように編集します。
- `@vitejs/plugin-react`インポートの追記
- `react(),`の追記
- `resources/ts/index.tsx'`と編集
- `'resources/scss/app.scss'`SCSSの追記
```vite.config.ts
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';

export default defineConfig({
    plugins: [
        react(),
        laravel({
            input: [
                'resources/css/app.css',
                'resources/scss/app.scss',
                'resources/ts/index.tsx'
            ],
            refresh: true,
        }),
    ],
});
```
## ②必要なモジュールのインストール
- TypeScriptのReactをインストール
- ViteでReactを利用するために@vitejs/plugin-reactのインストール
- TypeScriptをインストール
- Scssをインストール
- React用のTypeScriptの設置ファイル作成（tsconfig.json）
- react-router-domをインストール
```zsh
npm install
npm install -D react react-dom @types/react @types/react-dom
npm install -D @vitejs/plugin-react
npm install -D typescript
npm add -D sass
npx tsc --init --jsx react-jsx
npm i -D react-router-dom @types/react-router-dom
```
`-D`は`--save-dev`の略です。[--save-devとは](https://qiita.com/kohecchi/items/092fcbc490a249a2d05c)ローカルインストールするためのコマンドです

## ③index.tsx作成
今回はReact+TypeScriptを使用するので下記のようになるようディレクトリとファイルを作成します。
Viteで記載した`'resources/ts/index.tsx'`と同じようにする
```
resources
　　┗ ts
　　　　┗ index.tsx
```
## scssファイル作成
下記のようになるように作成する
```
resources
　　┗ scss
　　　　┗ app.scss
```
## ⑤packge.jsonの確認
packge.jsonにてインストールされているかの確認をします。
バージョン等は異なるかと思いますが、インストールした`@types/react` `@types/react-dom` `@vitejs/plugin-react` `sass` `typescript`が記載されていれば問題ないです。
```packge.json
{
    "private": true,
    "scripts": {
        "dev": "vite",
        "build": "vite build"
    },
    "devDependencies": {
        "@types/react": "^18.0.28",
        "@types/react-dom": "^18.0.11",
        "@types/react-router-dom": "^5.3.3",
        "@vitejs/plugin-react": "^3.1.0",
        "axios": "^1.1.2",
        "laravel-vite-plugin": "^0.7.2",
        "lodash": "^4.17.19",
        "postcss": "^8.1.14",
        "react": "^18.2.0",
        "react-dom": "^18.2.0",
        "react-router-dom": "^6.8.1",
        "sass": "^1.58.3",
        "typescript": "^4.9.5",
        "vite": "^4.0.0"
    }
}
```
## ⑥画面に表示してみる
以下のファイルを編集し、React側で作成した画面を読み込んで表示していきます
- `resources/views/index.blade.php`
- `routes/web.php`
- `resources/ts/index.tsx`
- `resources/scss/app.scss`


##### こちらは新規で作成するか、既存の`resources/views/index.blade.php`のファイル名を変更して編集どちらでも問題ないです。
コメントアウトはわかりやすいように記載しているだけなので、記載するとエラーになる場合があります。

```html 
 <!-- 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">

    <title>laravelView側タイトル</title>
    <!-- @viteReactRefresh は @vite() より先に読み込む必要がある -->
    @viteReactRefresh
    <!-- @vite() ではエントリポイントとなるファイルを指定 -->
    @vite([
    'resources/css/app.css',
    'resources/scss/app.scss',
    'resources/ts/index.tsx',
    ])
</head>
<body>
    <!-- index.tsxの内容を追加する部分 -->
    <div id="app"></div>
</body>
</html>
```
##### index.blade.phpを返すようにルートの設定お行う
```routes/web.php
Route::get('/', function () {
    return view('index');
});
```
##### 表示させたいReact側の処理を書きます
```resources/ts/index.tsx
import React from 'react';
import { createRoot } from 'react-dom/client';

// index.blade.phpのid="app"を読み込む
const container = document.getElementById('app');
const root = createRoot(container!); // createRoot(container!) if you use TypeScript

root.render(
    <div className="text-red">
        Laravel React+Typescript環境構築
    </div>
);
```
##### わかりやすいようにスタイルを当てます。スタイルはなんでも良いです。
```resources/scss/app.scss
.text-red {
    color: red;
    font-size: 50px;
    font-weight: bold;
}
```

### ブラウザで確認
サーバー起動してない場合は下記を実行し確認。
```
php artisan serve
```
このように表示されていれば問題ないです。
![laravelReact.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462658/fdaa133d-39c4-85c5-a474-717828fd094f.png)