対象
- Rails だけどSPAっぽく画面遷移したい
- SEO担保しないといけない
- 新規設計の参考
jQuery まみれの状態からこれと同等のことをするのは、不可能じゃないけど難しいです。
単にどう導入するか知りたいだけなら https://github.com/mizchi-sandbox/packnova/commit/447a91ea3a706c0bb0aac8570d1fbbaf6c9710f1 のコミットで
目指したモノ
最小限の設定で Rails エンジニアでもメンテ出来るSSR/SPAアプリの土台。
ただし土台をハックし始めるとその限りではない。。
スタック
- webpacker でコンパイル
- 画面遷移は hypernova-react/turbolinks で自動再マウント
ルーティングはRails側に寄せてます。なので react-router は入ってないです。
入れる選択肢もありますが、 react-router のSSRはとにかくだるいので、複雑さでメンテできなくなるのを考慮しました。代わりに turbolinks を引っ張り出しました。なのでオープンリダイレクタに気をつける必要があります。
シンプルさを優先してReduxは載ってないです。
どんな書き味か
<%= render_react_component('Header') %>
<%= render_react_component('App', name: 'Hypernova') %>
<%= render_react_component('Header') %>
<%= render_react_component('About') %>
import { renderReact } from 'hypernova-react'
import _App from './components/App'
import _About from './components/About'
import _Header from './components/Header'
export const App = renderReact('App', _App)
export const About = renderReact('About', _About)
export const Header = renderReact('Header', _Header)
renderReact の登録名を手がかりに、 rails のヘルパが引き直して render という感じ。
erbのヘルパの第二引数がルート要素への props になります。なので props の組み立ては Rails 側になります。API経由してガチャガチャやるよりこっちのがシュッとします。
画面切り替わり時は自動的にサーバーから降ってきたpropsを元に自動的に再render します。(警告が出ますが、React v16 で render => hydrate になったので、そのうち hypernova-react をアプデすれば直るでしょう)
実体としては script タグで json 埋め込んでそれを手がかりに評価してるという感じです。
SSR
rails s
でそのまま起動してもSPAとしては動きますが、SSRはしません。SSRしたければ 3001 に hypernova プロスセスを立てる必要があります。
yarn babel-node node/hypernova.js
標準出力に attached だか connected だか出てればOKです。
問題は、デプロイ時にこのnodeプロセスも一緒に立てないといけないって点ですね… ここはもうちょっと手を入れたい。
省いたこと
- webpacker についての詳細
- turbolinks で気をつけるべき挙動
これらは自分で調べてください。