技術と魚

技術調査、開発TIPS、駄文

React+RailsのSPA開発を色々と楽にするライブラリ、ServerComponent v0.xをリリースしました

Ruby on Rails と React を使ってSPA(Single Page App)を作っている方向けに、開発をより効率化するServerComponent (v0.x)をOSSとしてリリースしました。

このライブラリは端的にいうと、ReactのコンポーネントをRailsのControllerとして書けるようにすることを目指した集合体です。 と言ってもレンダリングを行うコンポーネントではなく、stateの状態管理とactionのつなぎ込みのみを行う、Container Component*です。


このリリース(v0.x)は、テクニカルプレビュー版を想定しています。大きく変更される可能性が高いので本番利用は今の所推奨していません。


f:id:norainu234:20190116203627p:plain

使い方

こちらから

Why?

Redux/Saga.. といったスタックが持つ高い汎用性と拡張性がSPAに常に必要とは限りません。過度にこだわった粒度の細かいモジュールよりも、少ないコードを保ちながら一定の品質のSPAを作るための方法が今のところ多くありません。 ServerComponentは、そうした代替手段の一つです。SPAの強みを維持しつつ、コードを極力減らしていくことができるので、開発効率が高くなります。

f:id:norainu234:20190119140445p:plain

背景

私は何度かReact/Railsの開発に携わってきましたが、どうしてもコード量が多くなってしまう問題に直面していました。

SPA(Single Page App)では(Reactを使った場合は特に)、UIコンポーネントは状態遷移機械のように抽象化できます。特定の機能要件は、ブレイクダウンしていくと「UIはある状態 Sからユーザの入力 pを受け取り、状態 S'に移る」という単位的要件に最終的に落とし込まれます。表示上のロジックを無視すると、この単位要件で実装するべきことは「与えられた S pから S'に移す関数 \delta: \delta(S, p) = S'であると考えることができます。

サーバーとのやり取りが必要な場合を考えます。サーバは大抵JSONを返すのが一般的です。サーバは現在のUIの状態を知らないので、リクエストに対し適切なレスポンスを返しておいて、それを使ってクライアント側で最終的に整える、という流れになることがほとんどです。

簡単のためリクエスト時のデータがユーザ入力 pそのものであると仮定します。サーバ側の状態(DB等)のことを無視すれば、サーバは「リクエスト pからレスポンス qを与える関数」と見做すことができます。そこでサーバを  F: F(p) = q とします。一方、前述の通りクライアントはレスポンス qと直前状態 Sから次の状態 S'を導くすると、その作用は関数  \delta': \delta'(S, q) = S' で表現できます。

ここで得られる  F,  \delta' を使うと、元の \delta

 \delta(S, p) = \delta'(S, F(p))

となり、従って \deltaを構成するためには、 F \delta'を構成すればよい、ということになります。 具体例で考えると、 FはRailsのController、 \delta'はReduxのReducer、といったものが該当します。

しかし..冷静に考えると、ただの状態遷移を書きたいだけであるにもかかわらず、サーバサイド( F)とクライアントサイド( \delta')の変更しないと開発が遂行できない上、わざわざ両者を分割して考えなければならないというのはかなり骨の折れる作業です。しかも、うっかり片方だけ変更してしまってはまずいので、堅牢性を高めようと思ったら、両者が前提に立つべきインターフェースをJSONSchemaか何かで宣言して、CIで検証するなどの方法が必要になってしまいます。

そこで、もしサーバ( F)がJSONのデータではなく、  \delta'にあたる関数を表現できたと仮定します。すると、 \deltaは単に

 \delta(S, p) = F(p)(S)

となり、そもそもクライアントサイドを何か変更する必要はなくなるはずです。これは例えば、setStateを含むJSのコードを直接返してしまうということです。馬鹿馬鹿しいような発想ですが、こうすることでサーバサイドだけの変更で完結し、コントローラの単体テストでコンポーネントの状態遷移を大体は検証できます

このようなアイディアからOSS化を目指したのがServerComponentです。

今後のロードマップ

  • まずは実用に耐える状態を目指す(v1.x)
    • 大体欲しくなる機能を追加
    • パフォーマンスのネックになりそうな部分を解決
  • ReactやRailsに依存しないレイヤーに広げていく

(しかし個人では限界がくる可能性が超超高いため、contributor様を随時募集しております🙇‍♂️🙇‍♂️)