14
Help us understand the problem. What are the problem?

posted at

updated at

【環境構築】LaravelでReactとTypescriptを使う方法

今回はLaravelでreactとTypescriptを使えるように開発環境を構築していきます。
初学者なので2週間ぐらいかかってしまいましたが誰かの参考になれば幸いです。

開発環境

Docker 20.10.5
docker-compose 1.28.5
php 7.3
laravel 6.20.26
Composer 2.0.8
MySQL 8.0
nginx 1.15.12-alpine

Dockerを使っていますがDockerの環境構築は省略させていただいてコンテナ内でlaravelをインストールするところから始めます。

Laravel&Reactの環境を整える

はじめにappコンテナに入りLaravelをインストールします。

# composer create-project --prefer-dist "laravel/laravel=6.*"



続いてLaravel/uiをインストール。
最新版のLaravel/uiをインストールするとLaravel6ではエラーが出るのでバージョン指定をしています。

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



Reactのスカフォールドをインストール。ついでに認証機能も追加しました。

# php artisan ui react --auth



webコンテナに入りnpmでインストールとビルドをします。(Dockerfileでnodeの設定済み)

# npm install & npm run dev

ここまででローカルサーバーにアクセスしたらちゃんとLaravelのwelcome.blade.phpのビューが表示されていたら成功です。

Laravel Mixを用いてTypescriptの環境を構築する

webコンテナに入りnpmコマンドでTypescriptで必要なパッケージをインストールします。
ついでにreact-router-domもこのタイミングでインストール。

# npm install ts-loader typescript react-router-dom @types/react @types/react-dom @types/react-router-dom --save-dev


webpack.mix.jsを編集

TypeScriptとSCSSでビルドできるようにwebpack.mix.jsを編集します。

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

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

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

reactをインストールしているのでデフォルトではおそらくmix.react()になっていると思いますがtypescriptをビルドするのでmix.ts()に変更します。
また、.version()を追加しておかないとnpm run devをしてもキャッシュが残っていて変更が反映されないことがあるので一応記述します。

tsconfig.jsonを作成

webコンテナ内で以下のコマンドを実行してtsconfig.jsonを作成します。

./node_modules/.bin/tsc --init



オプションが多いので適宜確認するしかないかと...
地味にエラーがよく出るのでエラー内容確認して適宜修正しました。

tsconfig.json
{
  "compilerOptions": {
      "outDir": "./built/",
      "sourceMap": true,
      "strict": true,
      "noImplicitReturns": true,
      "noImplicitAny": true,
      "module": "es2015", //フロント使用予定なのでcommonjsは使用しません
      "jsx": "react", // tsxファイルをjsxやjsにコンパイルする際の出力の形式を指定する
      "experimentalDecorators": true,
      "emitDecoratorMetadata": true,
      "moduleResolution": "node",
      "target": "es6",
      "lib": [
          "es2016",
          "dom"
      ],
      "allowSyntheticDefaultImports": true // エクスポートしないモジュールからのインポートを許可する。これでtypescriptでreactをインポートするときにimport React from 'react';を使えるようになる
  },
  "include": [
      "resources/ts/**/*" // TypeScriptのソース配置場所
  ]
}

tsxファイルを作成して表示されるか確認

tsxファイルが正しく表示されるか確認します。
まず、welcome.blade.phpを以下のように編集します。

resouces/views/welcome.blade.php
<!DOCTYPE html>
<html lang="ja">
    <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') }}" />
    </head>
    <body>
        <div id="app"></div>
    </body>
    <script src="{{ mix('/js/index.js') }}"></script>
</html>

次にresources配下にtsフォルダを作成し、その中にindex.tsxを作成します。
index.tsxは以下のように記述してください。

index.tsx
import React from 'react';
import ReactDOM from 'react-dom';

const App: React.FC = () => {
    return (
        <div>
            <p>こんにちは</p>
        </div>
    )
}

if (document.getElementById('app')) {
    ReactDOM.render(<App />, document.getElementById('app'));
}

そしてもう一度npm run devを実行しましょう。

# npm run dev

このままローカルサーバーで.index.tsxが表示されればいいのですが、僕の場合はTypeError: loaderContext.getOptions is not a functionというエラーが出ていました。
これはlaravelのバージョン(今回は6系を使用)に対してts-loaderのバージョンが新しすぎるために出るエラーのようです。

ts-loaderを一度アンインストールして古いバージョンを入れましょう。

# npm uninstall ts-loader
# npm install ts-loader@8.2.0 --save-dev

これで最後にもう一度npm run devを実行しましょう。

# npm run dev

0215c84b3c4c509e0985baad528ed419.png

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
14
Help us understand the problem. What are the problem?