初書:2021/09/06
mac : 11.5.2
php:v8.0.6
laravel:v8.57.0
前書き
最近Reactを知ったのでせっかくならLaravelでも使ってみよう、というメモ。
前提
Laravelインストール済み。
素のPHPしか触ってなかった人がlaravelを触ってみる - Qiita
インストール
まずはuiをインストール
% composer require laravel/ui
その後はuiをreactに変更
% php artisan ui react
インストールとmix
% npm install && npm run dev
もし、Please run Mix again.
と言われた場合はもう一度npm run dev
します。
以上
Typescriptにする
ReactといえばTypescript…と、勝手に思ってるので、Typescriptで書けるように追加していく。
インストール
まずは必要なものをインストール
% npm install --save-dev ts-loader typescript react-router-dom @types/react @types/react-dom @types/react-router-dom
react-router-dom
と@types/react-router-dom
はSPAを作る場合。laravel側でルーティングする場合は不要。
でもこの記事では使います。
tsconfig.jsonの設定
% npx tsc --init
これでtsconfig.jsonが生成される。
設定は好みだが、一応今設定しているものを置いておく。
{
"compilerOptions": {
"target": "ES2020",
"lib": [
"ES2020",
"DOM",
],
"jsx": "react-jsx",
"module": "AMD",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
},
"include": [
"resources/ts/**/*"
]
}
target
はES2020
を選択。頻繁なアプデを好まない層(IEとか古いiOSとか)がこないサイトなら最新のものでいいと思う。
module
はAMD
を選択した。es2020とかとの違いはあんまり分かってない。(非同期で読み込める点?でものちに1ファイルにまとめる・・・。)
各ブラウザの対応状況:ECMAScript 2016+ compatibility table
ページを作成する
今回はメインページとサブページを作る。
laravelでtsを置くのは基本的にresourcesディレクトリなので、この下に作成する。
import ReactDOM from "react-dom";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import main from "./main";
import sub from "./sub";
function App() : JSX.Element {
return (
<BrowserRouter>
<Switch>
<Route exact path="/" component={main} />
<Route exact path="/sub" component={sub} />
</Switch>
</BrowserRouter>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
import React from "react";
import { Link } from "react-router-dom";
const element = (): JSX.Element => {
return (
<div>
<p>メインページです。</p>
<Link to="/sub">サブページへ</Link>
</div>
);
};
export default element;
import React from "react";
const element = (): JSX.Element => {
return <p>サブページです。</p>;
};
export default element;
React、最近は関数型の書き方の方が良いって聞いたので関数型を使ってみた。
基盤となるapp.tsx
とページを表示するmainとsubを作成。
これが出来れば、それを表示するためのwelcome.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>Laravel</title>
</head>
<body class="antialiased">
<div id="root">
</div>
</body>
<script src="{{ mix('js/app.js') }}"></script>
</html>
表示用のdivと、読み込みスクリプトがあれば後は自由。
ページは以上
laravel mixを使う
そのままではapp.js
なるファイルは存在していないので、作成する。
普通にインストールしていると、webpack.mix.js
が既に存在しているので、これを編集する。
const mix = require('laravel-mix');
mix.js('resources/ts/app.tsx', 'public/js')
.react()
.webpackConfig({
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['*', '.js', '.jsx', '.ts', '.tsx'],
},
})
.version();
react()
が何するのかよく分かってない。誰か教えてください(他人頼り)
これで、npm run dev
を実行すると、先ほど作ったapp.tsx
関連がapp.js
にまとめられる。
一度アクセスしてみる
これで一度アクセスしてみる。
php artisan serve
でサーバーを立て、http://127.0.0.1:8000/
にアクセスすると、先程のメインページです
が表示されているはず。
また、サブページへを押すと、http://127.0.0.1:8000/sub
にアクセスされ、サブページです
が表示される。
一見これでいいように見えるが、直接http://127.0.0.1:8000/sub
にアクセスすると、laravel側からurlが存在していないと言われる。
これは、subページがReact内だけで作成されているだけのため。
この先は仕様次第だが、今回はReact側でアクセス処理を任せることにする
全てのアクセスをapp.tsxにまとめる
アクセスはroutes/web.php
で管理しているので、ここを変える
Route::get('/{any}', function () {
return view('welcome');
})->where('any', '.*');
元々あった/
を/{any}
に変え、条件を全てに変更した。
where文があるのは、/
もany
に含まれるようにするため。
これで、直接http://127.0.0.1:8000/sub
にアクセスしても、サブページです
が表示される。
終わりに
この後ブラウザとサーバー側でデータのやりとりをするため、APIの設定等をしないといけないが、長くなりそうなので今回は一旦ここで切り上げ。
まだ試行錯誤段階なので、やり方異なってたり、よりいい方法とかあれば更新する…かも。
参考サイト
React.JS + Laravel 8 + MySQL + API REST でCRUDを作ってみた。
【環境構築】LaravelでReactとTypescriptを使う方法 - Qiita