[Laravel] Reactのサーバーサイドレンダリング
PHPでのJavascriptのServer Side Renderringの方法としては、
- PHPで行う
- Node.jsなどでパースしたものを受け取る
のどちらかで実装しているみたい。
今回は1.のPHPで行ってみます。
便利そうなパッケージがあったので使います。
Composerでインストール
Installationの項目にある"minimum-stability": "dev"
をcomposer.jsonへ追記してreact-laravelをインストール。
$ composer require talyssonoc/react-laravel
$ php artisan vendor:publish
config/app.php
にReact\ReactServiceProvider
のプロバイダーを追記します。
なお、PHPのExtenstionとしてv8jsが必要
NPMのインストール
Reactを利用するだけであれば必要なさそうでしたが、JSXを利用する為には1度コンパイルする必要があるので必要なものを入れます。
package.json
{
"private": true,
"devDependencies": {
"gulp": "^3.8.8"
},
"dependencies": {
"buble": "^0.12.5",
"buble-loader": "^0.2.2",
"laravel-elixir": "^6.0.0-9",
"laravel-elixir-webpack-official": "^1.0.2",
"react": "^15.3.0",
"react-dom": "^15.3.0",
"webpack": "^1.13.1"
}
}
$ npm install
gulpの設定
react-jsでのJavascriptの読み込みが、デフォルトではpublic/js/components
なので、ここにJavascriptファイルがコンパイルされるよう追記します。
gulpfile.js
elixir(function(mix) {
mix.sass('app.scss')
.webpack('components.js');
});
コンポーネント作成
以下のファイルを作成してビルドします。
resources/js/components/WelcomeComponent.js
import React, { Component } from 'react';
class WelcomeComponent extends Component {
constructor(props, context) {
super(props, context);
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
alert(this.props.title);
}
render() {
return (
<div classname="title" onclick="{this.handleClick}">{this.props.title}</div>
);
}
}
export default WelcomeComponent;
resources/js/components.js
import WelcomeComponent from './components/WelcomeComponent';
var glob = typeof window !== "undefined" ? window : global;
glob['Welcome'] = WelcomeComponent;
作成後にコンパイル
$ gulp
Bladeファイルの編集
resources/view/welcome.blade.php
<title>Laravel</title>
<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css"><style>
html, body {
height: 100%;
}
body {
margin: 0;
padding: 0;
width: 100%;
display: table;
font-weight: 100;
font-family: 'Lato';
}
.container {
text-align: center;
display: table-cell;
vertical-align: middle;
}
.content {
text-align: center;
display: inline-block;
}
.title {
font-size: 96px;
}
</style><div class="container">
<div class="content">
@react_component('Welcome', [ 'title' => 'Laravel 5' ])
</div>
</div>
<script src="%7B%7B%20asset('vendor/react-laravel/react.js')%20%7D%7D"></script><script src="%7B%7B%20asset('vendor/react-laravel/react-dom.js')%20%7D%7D"></script><script src="%7B%7B%20asset('js/components.js')%20%7D%7D"></script><script src="%7B%7B%20asset('vendor/react-laravel/react_ujs.js')%20%7D%7D"></script>
動作確認
HTMLソース上に表示されました!
<div data-react-class="Welcome" data-react-props='{"title":"Laravel 5"}'><div class="title" data-reactid=".28w8vglweoy" data-react-checksum="-1540418249">Laravel 5</div></div>
また、見出し部分をクリックするとアラートが表示されることも確認。