🍐

Laravel 8のフロントエンド環境をReact+TypeScriptにする

2021/09/12に公開

概要

Laravel標準のフロントエンド環境を自分好みにカスタマイズします

方針

  • React+TypeScriptで画面を書く
  • Laravel Jetstream、Breezeを使わない(Livewire/Inertia.jsやAlpine.js、Blade Componentsが付属して入ってくるので)
  • Bladeテンプレートは画面構成に使わない
  • SPAにする
  • SSRはしない
  • Laravel Mixでアセットを管理する

なぜこうするかというとフロントエンドの環境だけ分離できる状態を維持しておいて、あとで複数人開発への移行やデプロイ分割をしたいためです。

NPMモジュールインストール

"devDependencies": {
    "axios": "^0.21",
    "laravel-mix": "^6.0.6",
    "lodash": "^4.17.19",
    "postcss": "^8.1.14"
},

なぜかデフォルトで入っている package.json 内の lodash は消します(いらないので……)。axiosは使いそうなので残しておきます

npm i

React+TypeScript化

TypeScript関連モジュールを追加します

npm i --save-dev ts-loader typescript @babel/preset-react

このままコンパイルすると TS18002: The 'files' list in config file 'tsconfig.json' is empty. と出て失敗するので tsconfig.json を作っておきます

npx tsc --init

デフォルトの設定だと can only be default-imported using the 'esModuleInterop' flag TS17004: Cannot use JSX unless the '--jsx' flag is provided. が出てコンパイルできないので変更します

{
  "compilerOptions": {
    "target": "es5",
    "jsx": "preserve",
    "module": "es2020",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  }
}

React関連モジュールを追加します

npm i --save react react-dom @types/react @types/react-dom

エントリーポイント resources/js/app.jsresources/js/app.tsx にリネームして最初のReactコンポーネントを記述します

import React from "react";
import * as ReactDOM from 'react-dom';

function App() {
    return (
        <div>
            Hello
        </div>
    )
}

ReactDOM.render(<App />, document.getElementById('app'))

webpack.mix.js の設定をReact+TypeScript用に変更します

mix.ts('resources/js/app.tsx', 'public/js')
    .react()
    .postCss('resources/css/app.css', 'public/css', [
        //
    ]);

resources/views/welcome.blade.php へReactコンポーネントをマウントする id="app" とmixでコンパイルしたJavaScriptを読み込みscriptタグを追加します

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

        <title>Laravel</title>
        <link rel="stylesheet" href="{{ mix('css/app.css') }}">
        <script src="{{ mix('js/app.js') }}" defer></script>
    </head>
    <body>
        <div id="app"></div>
    </body>
</html>

ルーティング

SPAにしたいのでreact-routerをインストールします

npm i --save react-router-dom @types/react-router-dom

routes/web.php を編集しどのパスへのアクセスでも resources/views/welcome.blade.php を描画するようにします

Route::view('/{path?}', 'welcome');

UIフレームワーク

Chakra UIMaterial-UI など好きなものをインストールして使います

Discussion