【Laravel】Laravel 6系プロジェクトにReact + TypeScriptを部分的に導入する

#はじめに
Laravel(6系)で作成したプロジェクトで、フロントエンドの一部をReactに置き換えました。
ReactおよびTypeScriptを導入するにあたり、何箇所かひっかかったところがあったので、メモとしてまとめることにしました。

#Reactの導入
Laravel上でフロントエンドのフレームワーク(React, Vue.jsなど)を使うために、laravel-uiというライブラリを導入します。
Laravel6系ではlaravel-ui 1.xに対応しているので、以下のコマンドでインストールします。

```
composer require laravel/ui:^1.0 --dev
```

Laravelのスカフォールド(デフォルトの対応フレームワーク)はVue.jsなので、これをReactに切り替えます。

```
php artisan ui react
```

Reactに切り替えることで、以下のファイルが編集または生成されます。

```
編集 [resources\js\app.js]
編集 [resources\js\bootstrap.js]
生成 [resources\js\components\Example.js]
```

`app.js`はLaravel Mixでビルドする際のルートのファイルとなります。
初期設定では`require('./components/Example');`となっていますが、例えば`/src/index.jsx`をルートにしたい場合などは、require('./src/');のように書き換えます。

```js:resources\js\app.js
require('./bootstrap');
require('./components/Example');
```

各パッケージのインストールおよびビルド(開発用)を作成します。

```
npm install　&& npm run dev
```

bladeファイルでビルドファイルを読み込むために以下を追記します。

```php:example.blade.php
    <link href="{{ asset('/css/app.css') }}" rel="stylesheet" type="text/css">
    <div id="example"></div>
    <script src="{{asset('/js/app.js')}}"></script>
```

Laravel側のRouteの設定について、SPAに対応できるようReactのページ部分については`{any}`とします。

```php
Route::get('profile/{any}', 'ProfileController@getProfile')->where('any', '.*');
```

#TypeScriptの導入
必要なパッケージをインストールします。

```
npm install -D typescript ts-loader react-router-dom @types/node @types/react @types/react-dom @types/react-router-dom
```

`tsconfig.json`を作成します。
`.ts` `.tsx`ファイルの配置を`include`で指定します。

```json:tsconfig.json
{
    "compilerOptions": {
        "outDir": "./built/",
        "sourceMap": true,
        "strict": true,
        "noImplicitReturns": true,
        "noImplicitAny": true,
        "module": "es2015",
        "jsx": "react",
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "moduleResolution": "node",
        "target": "es6",
        "lib": [
            "es2016",
            "dom"
        ],
        "allowSyntheticDefaultImports": true
    },
    "include": [
        "./resources/ts/**/*.tsx",
        "./resources/ts/src/types/**/*"
    ]
}
```

`.js` `.jsx`のファイルを`.ts` `.tsx`に置き換えます。
そして、`webpack.mix.js`ファイルも書き換えます。
第二引数でビルドファイル名やビルド先を指定しています。

```js:webpack.mix.js
const mix = require('laravel-mix')

mix
  .ts('resources/ts/app.tsx', 'public/js/app.js')
  .sass('resources/sass/app.scss', 'public/css/aop.css')
  .version()
```

Laravel Mix関連でエラーがでたらアップデートします。

```
npm install -D laravel-mix@latest && 
npm install -D sass-loader@latest && 
npm install -D postcss@latest && 
npm install -D webpack@latest
```

`package.json`の`scripts`を以下のようにします。

```
"scripts": {
    "dev": "npm run development",
    "development": "mix",
    "watch": "mix watch",
    "watch-poll": "mix watch -- --watch-options-poll=1000",
    "hot": "mix watch --hot",
    "prod": "npm run production",
    "production": "mix --production"
}
```

開発中は`npm run watch`でファイル修正を監視しながら開発ビルドを実行することができます。
本番用のビルドファイルを作成する際には`npm run production`を実行します。

これでも何かエラーがでたら、添付の資料を参考にしてみてください。

#参考資料

https://atuweb.net/202003f_laravel-ui-composer-error/

http://www.code-magagine.com/?p=10606

https://qiita.com/mineaki27th/items/ad774a41b7a0a68761bd

https://qiita.com/yuuumbk/items/b5da5b6f8c8ca24c7974

https://brainlog.jp/programming/laravel/post-2332/