先日Laravel9がリリースされた。Laravelは6の知識で止まっていたことと、最近LaravelのフロントにReactやVueを持っていきたいということがあって久しぶりにLaravelを触ってみた。今回はReactを入れていきます。
自分はLaravelもReactもどちらも独学の初学者レベルなので、同じようにやってみたい初心者向け。
今回はlaravel/uiというパッケージを使用してReactを使っていく。公式ではlaravel/uiは非推奨になっており、Laravel Breeze経由でReact等を入れてくれと書いてあったがそっちは難しすぎてギブした。Laravel Breeze経由でReactやVueを入れると、Inertia.jsというよくわからないものを学習する必要がありそう。
フルスタックなのかAPIサーバーなのか
いきなり本題に入る前に、押さえておきたいことが一つ。
それは、Laravelの中にReactを組み込むのか、LaravelとReactをそれぞれ独立して作ってあとで合体するのかどちらかということ。そもそも自分がこれを全く理解していなかった為に、色々な記事や動画を見ても今ひとつ要領を得られなかった。
見出しのフルスタックというのはLaravelの中にReactを組み込んでいくやり方で、今までBlade文に色々書いてきた部分をReactに変更するということ。今回紹介する方はこっち。
もう一つのAPIサーバーとして使うというのはLaravelとReactのプロジェクトを完全に分けてReactからアクセスした時にLaravelがjson形式でデータを返すAPIサーバーとして使うというもの。
Laravel公式にも記載がある通りどちらのやり方でもできる。どちらにせよLaravelの役割はDBとのやりとりになると思う。また、それぞれ独立させる場合はデプロイする時にそれぞれホスティング先を分ける必要はあるかも。
Laravel The Full Stack Framework
Laravel The API Backend
最近だとおそらくフロントエンドとバックエンドを切り分けることでチームで開発するのが楽になるからそれぞれ独立して作った方がよさそう。
さらに言えば、DBとしての役割はいまFirebaseとか様々なDBがサービスとして提供されているので、何か個人でサービスを作るならフロントとそっちを勉強すればよい気がするがLaravelを最初に触った身としてはある程度できるようになりたいので今回記事としてまとめる。
だいぶ前置きが長くなってしまったが、初心者の人は記事や動画を見る時にLaravelの中にReactを組み込んでいるのかそれぞれ別で作っているのかを意識すれば少しは見やすくなるのではないか。
Laravelプロジェクトを作成する
では、まずはLaravelプロジェクトを自分のローカルマシンに作成する。Laravel sailを使っても良いし、composer経由でもどちらでも。自分は触りだけなので、composerを使っていきます。
Laravel自体のインストール方法が分からなければどちらか参考にしてください。
ターミナルを準備して、好きなディレクトリにLaravelを作成しよう。ちなみにLaravel最新のバージョン9ではPHPのバージョンが8以上じゃないと動かないから、最新のLaravelを使用したい人はPHPのバージョンも上げておこう。
ターミナルで以下のコマンドを入力。example-appの部分は好きな名前で。また--prefer-distオプションをつけてもつけなくても。(これはいまだによくわかっていないがどうやらダウンロードする形式らしい。Githubからzipで落としているっぽい?)
composer create-project laravel/laravel example-app
laravel/ui パッケージをインストール
Laravelプロジェクトを作成できたら次にlaravel/ui
パッケージをインストールする。composerのパッケージとして登録されているのでcomposerコマンドを叩いて落としてくる。
上で作成したLaravelプロジェクトのフォルダ上でコマンドを入力。
composer require laravel/ui
Reactをインストールする
laravel/ui
パッケージをインストールしてきたら、次は以下のコマンドでReactのインストール準備をする。
php artisan ui react
認証機能も使いたいひとは--auth
オプションをつけるだけで認証機能も入れてくれるみたいだ。
php artisan ui react --auth
laravel/ui
パッケージのGitHubを見てもわかる通り、reactだけではなく、vueやbootstrapでも入れられるみたいだ。
今回認証機能はいらないでの、--auth
オプションは外しておく。
コマンドを入力すると以下のような文が返ってくるはずだ。これでReactをインストールする準備が整った。
この段階でpackage.json
ファイルを見てみると、新しくreact
に関するものが追加されており、ついでにsass
も書かれている。sass
はcssを便利にしたようなやつだ。
Reactをインストールする準備が整ったら、上にあるように、npm install && npm run dev
コマンドを入力しよう。
これはnpm install
とnpm run dev
を&&
でまとめて実行しているだけなのでもちろん一つずつ順番にやっても構わない。
※追加のパッケージを入れる必要があれば入れる
npm install && npm run dev
コマンドを実行すると自分の場合以下のように"追加のパッケージを入れてください"と指摘された。
指示通り追加のパッケージをインストールしたら、以下のようになるはずだ。
最後にnpm run dev
コマンドを入力するとwebpack compiled successfully
と返ってきて準備完了だ。
コマンドの入力に成功すると、resources/js
フォルダ以下にcomponents
フォルダが作成されており、その中にExample.js
コンポーネントが見える。これがReactのコンポーネントだ。
import React from 'react';
import ReactDOM from 'react-dom';
function Example() {
return (
<div className="container">
<div className="row justify-content-center">
<div className="col-md-8">
<div className="card">
<div className="card-header">Example Component</div>
<div className="card-body">I'm an example component!</div>
</div>
</div>
</div>
</div>
);
}
export default Example;
if (document.getElementById('example')) {
ReactDOM.render(<Example />, document.getElementById('example'));
}
上記がExample.jsの中身だ。このコンポーネントを次は表示させていく。
welcome.blade.phpを書き換える
さて、いよいよこれでreactを使えるようなったが、もちろんこのままではまだ何も変わらない。php artisan serve
でローカルサーバーを立ち上げてもいつものLaravelが出てくるだけだ。
上のExample.jsコンポーネントを表示させる為に、いくつか要素を書き換えていこう。まず最初はwelcome.blade.php
を変更する。
Laravelのweb.phpにはルーティングが書かれており、/
にアクセスするとviewsフォルダの中のwelcome.blade.php
が返される。この中身が最初のLaravelのトップページに繋がるのでこれを書き換える。
welcome.blade.php
を以下のように変更する。styleとbodyの中身を消しただけだ。
<!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>
ここにReactのコンポーネントを表示させたい
</body>
</html>
新しくbodyの中に適当に文字を入力した。この中でReactのコンポーネントのExample.jsコンポーネントを表示させていく。
このままだとbodyの中に文字を足しただけなので、Exampleコンポーネントにアクセスするためにbodyの中身に以下の2行を追加する。
<div id="example"></div>
<script src="{{ mix('js/app.js')}}"></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>
</head>
<body>
<div id="example"></div>
<script src="{{ mix('js/app.js')}}"></script>
</body>
</html>
改めて、ブラウザで表示を確認してみるとExample.jsで書かれているものが表示されているはずだ。
新たに書き加えたコードを見ていこう。
<div id="example"></div>
の部分でid属性にexampleと書いている。これはExapmleコンポーネントの中でgetElementByIdでアクセスさせる為の記述だ。
if (document.getElementById('example')) {
ReactDOM.render(<Example />, document.getElementById('example'));
}
getElementByIdメソッドでexampleを指定して、もしそれがあればExampleコンポーネントを表示してねという意味だ。
bodyの中身の2行目、<script src="{{ mix('js/app.js')}}"></script>
部分でjsフォルダのapp.jsを読みこんでいる。mixメソッドはよくわからないがコンパイルする上で必要なのかな?
/**
* First we will load all of this project's JavaScript dependencies which
* includes React and other helpers. It's a great starting point while
* building robust, powerful web applications using React + Laravel.
*/
require('./bootstrap');
/**
* Next, we will create a fresh React component instance and attach it to
* the page. Then, you may begin adding components to this application
* or customize the JavaScript scaffolding to fit your unique needs.
*/
require('./components/Example');
このapp.jsファイルの中で、Exampleコンポーネントを読み込んで表示している。
<div id="example"></div>
<script src="{{ mix('js/app.js')}}"></script>
上の2行のどちらが欠けても表示されないので気をつけよう。
次にstyleを当てていくために、welecome.blade.phpの中でcssを読み込む。
<!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')}}">
</head>
<body>
<div id="example"></div>
<script src="{{ mix('js/app.js')}}"></script>
</body>
</html>
<link rel="stylesheet" href="{{mix('css/app.css')}}">
の1行を追加してブラウザを確認するとbootstrapのスタイルがあたっていることがわかるはずだ。
Exampleコンポーネントを書き換える
これでExampleコンポーネントが表示されるようになったので、試しにExampleコンポーネントの中身を書き換えてみよう。
import React from 'react';
import ReactDOM from 'react-dom';
function Example() {
return (
<div className="container">
<div className="row justify-content-center">
<div className="col-md-8">
<div className="card">
//適当に変更する
<div className="card-header">テストです</div>
<div className="card-body">二郎が食べたいです</div>
</div>
</div>
</div>
</div>
);
}
export default Example;
if (document.getElementById('example')) {
ReactDOM.render(<Example />, document.getElementById('example'));
}
書き換えた後に再度ブラウザをアクセスしても、変更が反映されていないはずだ。
なぜなら、ReactコンポーネントやVueコンポーネントを変更したら毎回npm run dev
コマンドを入力してビルドする必要があるためだ。
npm run dev
コマンドを入力した後にブラウザを確認すると変更が反映されているはずだ。
ただブラウザを更新しても変更されないので注意しよう。
どこにアクセスしてもwelcome.blade.phpを返すようにする
これでほとんど問題ないが、最後にweb.phpでルーティングを変更していこう。
ReactはSPAと言って、HTML一つでDOMだけを書き換えてページを変更していく。つまりこの場合は全ての起点にwelcome.blade.phpが返されるようにしたい。どのURLにアクセスしても、welcome.blade.phpにつながりそこで読み込んでいるExampleコンポーネントが返される。後はReactのコンポーネントをこの中で色々用意してページを作っていく感じだ。
今適当なパラメーターをくっつけると404が返されるはずだ。試しにパラメータをつけてアクセスしてみる。
これをどのページにアクセスしても、welcome.blade.phpが返ってくるようにweb.phpを書き換えていこう。
Route::get('{any}', function () {
return view('welcome');
})->where('any','.*');
詳しいことはわからないが、上のコードでどこのURLにアクセスしてもwelcome.blade.phpが返ってくるようになった。
まとめ
- Laravelプロジェクトを作成し、laravel/uiパッケージを落とす。
- laravel/uiパッケージからreactを落とし、npm install && npm run devコマンドを走らせる。(追加で必要なパッケージがあれば入れる。)
- welcome.blade.phpとExampleコンポーネントを書き換える。
- どこにアクセスしてもwelcome.blade.phpが返されるようにweb.phpを書き換える
こんな感じだろうか。知らないメソッドも中にあってだいぶ大雑把だがこれでLaravelの中でReactを使えるようになった。理解したら書き加えていきたい。また、次はLaravelとReactのプロジェクトをそれぞれわけて作成してみたい。少しでも参考になれば幸いです。