java + react.jsでsever side rendering #reactjs_meetup
TRANSCRIPT
Java + React.jsで Sever Side Rendering2015-04-24 React.js meetup #1 LT
Toshiaki Maki (@making)
自己紹介•@making
•Java界隈にいます
•Spring Framework好き
自己紹介•@making
•Java界隈にいます
•Spring Framework好き
「はじめてのSpring Boot」 著者
自己紹介•@making
•Java界隈にいます
•Spring Framework好き
「はじめてのSpring Boot」 著者
Spring IO 2015スピーカー
私とServer Side Rendering• SPAでブログ作った!
Backend API
(Java)
Frontend SPA
(Backbone.js)
Backend SPA
(Backbone.js)
REST API
REST API
http://blog.ik.am
https://github.com/making/categolj2-backend
_人人人人人人人_ > ググれない < ‾Y^Y^Y^Y^Y^Y‾
_人人人人人人人_ > ググれない < ‾Y^Y^Y^Y^Y^Y‾
アフィリエイト収入が 1/4に😭
はてブ
はてブ
_人人人人人人人_ > Loading... < ‾Y^Y^Y^Y^Y^Y‾
Sever Side Rendering やるしかない!
SSR候補
•Prerender •Rendr (Backbone.js) •React.js
SSR候補
•Prerender •Rendr (Backbone.js) •React.js 採用理由:
流行っているから
React.jsで SSR?
React.jsで SSR?
それJavaでもできるよ
JavaScript Engine in Java
• ScriptEngine API (JSR-223)
• Java SE 6, 7 … Rhino
• Java SE 8 … Nashorn
JavaScript Engine in Java
• ScriptEngine API (JSR-223)
• Java SE 6, 7 … Rhino
• Java SE 8 … Nashorn
JavaとJavaScriptの関係はインドとインドネシア の関係ほど単純じゃない
ScriptEngine
ScriptEngineManager engineManager = new ScriptEngineManager(); ScriptEngine engine = engineManager.getEngineByName("js"); engine .eval("function sum(a,b){return a + b;}"); System.out.println(engine.eval("sum(1,2);")); // 3
http://www.oracle.com/technetwork/articles/java/jf14-nashorn-2126515.html
ScriptEngineを使って Sever Side Rendering
V8バインディングいらず!
React.js側のコードwindow.renderOnClient = function (initialData) { React.render( <App data={initialData} />, document.getElementById('content') ); }; window.renderOnServer = function (initialData) { //initialData = Java.from(initialData); Listの場合 return React.renderToString( <App data={initialData} /> ); };
React.js側のコードvar App = React.createClass({ render: function () { return ( <div> <h1>React.js</h1> <Greet data={this.props.data} /> </div> ); } }); サーバーサイドで用意さ
れたデータが渡される
React.js側のコード
var Greet = React.createClass({ getInitialState: function () { return this.props.data || {id: 0, content: 'Now Loading...'}; }, // … });
getInitialState()でサーバーで用意したデータを返す
サーバーサイド// JSONマッパー ObjectMapper objectMapper = new ObjectMapper(); // ScriptEngineのラッパー ScriptEngine engine = new JavaScriptEngine() .polyfill() .load("static/bundle.js") .get(); @RequestMapping("/") String index(Model model) throws Exception { Greet initialData = new Greet(100, "Data on Server"); Object markup = ((Invocable) engine) .invokeFunction("renderOnServer", initialData); model.addAttribute("markup", markup); model.addAttribute("initialData", objectMapper.writeValueAsString(initialData)); return "index"; }
HTMLテンプレート(Thymeleaf)
<body> <div id="content" th:utext="${markup}"></div> <script src="bundle.js"></script> <script type="text/javascript" th:inline="javascript"> document.addEventListener("DOMContentLoaded", function () { var initialData = JSON.parse(/*[[${initialData}]]*/ '{"id": -1, "content": "モックデータ"}'); renderOnClient(initialData); }, false); </script> </body> エンジン経由だとコメントの中身が評価される
テンプレートを直で開くとコメントの後ろが評価されるので、フロントエンドに閉じて開発可能!
サーバーで生成したHTMLを埋め込む
componentDidMount (Ajax)
SSRできた!
JSも評価されてる
ということで フロントをReact.jsで作り直した
Backend API
(Java)
Frontend SPA
(React.js)
Backend SPA
(Backbone.js)
REST API
REST API
https://github.com/making/categolj2-backend/tree/master/frontend-ui-reactjs
ぐぐれ・・・・
ぐぐれとるやん
ん?
ん?ブログのフロントエンドはReact.jsで書いてみたけど SSR対応はまだだった!!
ん?ブログのフロントエンドはReact.jsで書いてみたけど SSR対応はまだだった!!
Google先生が優秀だった
まとめ•NashornがあればJavaでもサーバーサイドレンダリングできた
•Google先生はSPAに対応していた 今日のソースコード
https://github.com/making/ssr-demo