31
29

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

VirtualDOMAdvent Calendar 2014

Day 15

PHPでReact.jsのサーバサイドレンダリング

Last updated at Posted at 2014-12-20

こんにちは。VirtualDOM Advent Calendar 15日目のdekokunです。

14日目はtomato360さんの「React.jsのチュートリアルを触る」でした。

要約

JSで描画する内容を事前にサーバサイドレンダリングするようにすると嬉しい事がいろいろ増えますが(詳細:React.jsとserver-side rendering)、PHPでもできるようだったのでやってみました。というお話。

結論:react-php-v8jsはメンテされていない

使うライブラリ

使い方を簡単に

  • 頑張ってV8Js PHP extensionをpeclでインストールする
    • そのためには頑張ってV8エンジンをインストールする必要がある。
  • なお、私は上記もろもろが非常に厳しかったため、V8Js PHP extensionがインストール済みのDockerイメージを使用しました。stesie / v8js

コード

以下参照

上記注意しなくてはいけないのは、react.jsのバージョンです。なんと、2014/12/20現在のreact-php-v8jsのmaster時点(といっても最終コミットは10ヶ月前)で、最新版の0.12で動かないのは当然(?)として、0.8.0じゃないと動きません。

イメージ的には以下の使い方です。

<?php
$react = new ReactJS(
  file_get_contents('/path/to/react.js'), // react。バージョンは0.8.0で
  file_get_contents('/path/to/content.js') // 自分のアプリをconcatしたJS
);

// reactのrenderで指定するpropsを生成。
$data =
  array('data' => array(
    array(1, 2, 3),
    array(4, 5, 6)
  )
);

// 以下と同様のレンダリングを行えっていうことっぽい (reactのバージョン注意)
// React.renderComponent(Table({"data":[[1,2,3],[4,5,6]]}), document.getElementById("page"));
$react->setComponent('Table', $data);
?>

<!doctype html>
<html>
  <head>
    <title></title>
  </head>
  <body>

    <!-- getMarkupが、レンダリングされたHTMLを返している -->
    <!-- data-react-checksumも入っているため、それが正しければ再レンダリングは行われない -->
    <div id="page"><?php echo $react->getMarkup(); ?></div>

    <script src="react.js"></script>
    <script src="content.js"></script>

    <script>

    <!-- 以下JSが出力される なお第二引数に文字列を渡すとその名前の変数に結果を代入するJSが出力される  -->
    <!-- React.renderComponent(Table({"data":[[1,2,3],[4,5,6]]}), document.getElementById("page")); -->
    <?php echo $react->getJS('#page'); ?>
    </script>
  </body>
</html>

メンテナンスがされていないせいでReact.render()というナウい書き方じゃなくてReact.renderComponent()だったりして趣深い

react-php-v8jsの内部

クラスが1つあるだけです。ReactJS::setComponent()で、component名、及びpropsをjson_encode()したものを内部に持ち、ReactJS::getMarkup()でV8Jsに対してReact.renderComponentToString()を渡してあげて出力をそのまま返している

中が非常にシンプルな作りであるため、新しいReact.jsで使いたい場合でも簡単に対応できますね。

最後に

今日は2014/12/20です。15日目のアドベントカレンダーを今日書いています。

実は一度(草稿)JS弱者がBackboneでアプリ書いてて思った「VirtualDOMだったらここがよくなるだろうな」ってことを、ここの識者たちに「この理解でいいの?」って聞きたいというのを書いていたのですが、インフルエンザですごく適当なものを世に出してしまい、どうせならもうちょっとまともな別の記事書くかってなって慌ててPHPでサーバサイドレンダリング調べました。

PHPならJS弱者の私でも楽勝だぜ!!!って思いましたが、まずV8Js PHP extensionのインストールに死ぬほどもがき苦しみ、諦めてdocker使おうとしたけどdockerに慣れておらずもがき苦しみ、reactのバージョンも最新では動かず少しずつバージョンを落としながら試してみたりして結構地獄感ありました。

なお、現状、V8Js PHP extensionをCentOSで動かす方法が見つけられていません。世の中、難しいもんですねと思いました。

V8エンジンをcompileしようとして死にそうになっているところ

31
29
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
29

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?