62
なぜ私はVue.jsを諦め Flux + React移行したのか 社内JavaScript現状確認会

Flux react現状確認会

Embed Size (px)

Citation preview

Page 1: Flux react現状確認会

なぜ私はVue.jsを諦め Flux + Reactに 移行したのか

!社内JavaScript現状確認会

Page 2: Flux react現状確認会

前提となる適用先• 管理画面的なWebアプリケーションのリニューアル

…だったもの(仮)

• REST APIを前提としたSingle Page Applicationもどき

(※すべてが1ページではないけど)

• 機能・画面が多い

• 複雑化することがほぼ確実

Page 3: Flux react現状確認会

Viewへの要求事項• 統一されたスタイルでUIとなるHTMLを生成できる

• なるべく簡単に書けること(含セキュリティリスク回避)

(生DOM・jQueryはあり得ない)

• 業界におけるパラダイムが過渡期のため、

巨大フレームワークに乗っかりたくは無い(交換可能な部品の組み合わせでプレーンに)

• 困ってもなんとか出来るための緊急ハッチも必要

Page 4: Flux react現状確認会

まずFluxを採用した話

Page 5: Flux react現状確認会

What is Flux?

Page 6: Flux react現状確認会

It’s not any framework, is just an architecture.

Page 7: Flux react現状確認会

Flux アーキテクチャ• Facebook提唱のGUIアプリのアーキテクチャ

• オブザーバパターンを用いる

• データの流れる方向を単一にする

• 特定のライブラリに依存する思考ではないと解釈している

Page 8: Flux react現状確認会

Flux 概念図

https://github.com/facebook/flux

Page 9: Flux react現状確認会

Fluxのメリット• データの入力と出力のフローが一定になる

• 「あるモジュールに入力が起きた場合、次はどこにデータが来るか?」を規約したアーキテクチャ

• なので、デバッグ的な予測がしやすい

• MVC方言にありがちな概念の言語化

Page 10: Flux react現状確認会

Fluxの辛いところ• 定着した概念ではないので、オレオレFluxが乱立している(情報収集の難)

• 冗長な箇所もある(ほぼ必ずサイクルを一周しなければいけない)

• Store->Viewの通知粒度を細かくしないと、

一般的にViewの更新コストが非常に大きい

Page 11: Flux react現状確認会

何を使ってViewを実装するか?

Page 12: Flux react現状確認会

今回のViewへの要求事項• 統一されたスタイルでUIとなるHTMLを生成できる

• なるべく簡単に書けること(含XSS回避)

• 交換可能な部品の組み合わせでプレーンに.

• 困ってもなんとか出来るための緊急ハッチも必要

(生のDOM APIを触る方法がある)

Page 13: Flux react現状確認会

First, I used Vue.js

Page 14: Flux react現状確認会

※以後のVue体験記は

2014年8~9月初頭の、

v0.10.xの印象である

Page 15: Flux react現状確認会

Vue.js (vuejs.org)

• Model View ViewModel (MVVM) pattern • ES5でデータバインディングする

• Angularのデータバインディングだけ切り出したようなもの

• イケイケJSライブラリの割にドキュメントが文明的

Page 16: Flux react現状確認会

「良い」というよりも「楽」

• 宣言的に書ける • データバインディング

• データを渡せば勝手に表示してくれる • 紐づければ勝手に更新される

• 記述量も少なめ

Page 17: Flux react現状確認会

けれどもな

Page 18: Flux react現状確認会

個人的にイマイチ感あった

• 規約らしいものはあんまりない • 「Vue.jsの考えるViewModel」が言語化されているとは言いがたい

• 特に値と状態の区別が無いのは好きではない(ビュー層の宿命ではあるが)

• Vueのテンプレート定義は複雑な記述が面倒くさい

• 個人的にJSコードとバインド先の記述の分断を感じる • プロトタイプチェーンを書き換える(※最近、改良された)

Page 19: Flux react現状確認会

プロトタイプチェーンを書き換えやがって(^ω^)こういうチェーンがあるじゃろ?

!Hoge  |  V  Hoge.prototype  |  V  Object.prototype

Page 20: Flux react現状確認会

プロトタイプチェーンを書き換えやがって(^ω^)Vue.jsにHogeを渡すじゃろ?

!Vue({      data:  {          bar:  Hoge,      },  })

Page 21: Flux react現状確認会

プロトタイプチェーンを書き換えやがって(^ω^)Vue.jsはこう書き換えるじゃろ?

!Hoge  |  V  <Vueの変更監視用プロパティ>  |  V  Object.prototype

Page 22: Flux react現状確認会

プロトタイプチェーンを書き換えやがって(^ω^)Hoge.prototypeは行方不明じゃろ?

!Hoge  |  V  <Vueの変更監視用プロパティ>  |  V  Object.prototype

Page 23: Flux react現状確認会

プロトタイプチェーンを書き換えやがって(^ω^)toString()すらも行方不明じゃろ?

!Hoge  |  V  <Vueの変更監視用プロパティ>  |  V  Object.prototype

Page 24: Flux react現状確認会
Page 25: Flux react現状確認会

※最近のバージョンで prototype残してくれるらしい

Page 26: Flux react現状確認会

結局、Vue.jsは断念

• Backbone.Stickitなどからの移行には有用ではないかと感じる !

• しかし、2014年秋現在、これでゼロから作るかは悩みどころ !

• 生のオブジェクトを扱えないのは悲しい

Page 27: Flux react現状確認会

そうだ、React行こう

Page 28: Flux react現状確認会

React

• View特化ライブラリ(render library)

• 自動差分描画機能を持つ(Virtual DOM)

• データと状態の概念がAPIレベルで 分かれている

• ドキュメントが本当に細かい

(github:facebook/react)

Page 29: Flux react現状確認会

本当のDOMツリー

SyntheticEvent(Virtual Event)

Virtual DOM

差分描画機構React

JSReactのある生活

ユーザー

Page 30: Flux react現状確認会

Virtual DOM

<div>      <h1>bar</h1>    <p>foo</p>  </div>

div

h1 p

bar foo

テンプレートエンジンとして、文字列ではなく木構造を作る

Page 31: Flux react現状確認会

div

h1 p

bar foo

div

h1 p

bar

差分計算の概念図

生成した木構造を中間表現として扱い,データ構造としての比較を行う

Page 32: Flux react現状確認会

本当のDOMツリー

SyntheticEvent(Virtual Event)

Virtual DOM

差分描画機構React

JSデータの表示フロー(概略)

人間

Page 33: Flux react現状確認会

本当のDOMツリー

SyntheticEvent(Virtual Event)

Virtual DOM

差分描画機構React

JSDOMイベントの発生フロー(概略)

人間

Page 34: Flux react現状確認会

Reactのメリット• 実際のDOMの変更処理をReactに丸投げ可能

• 必要なデータを全て一度に入力しても、

自動で差分が計算されるので、常にある程度の速度で描画が可能

• 「参照透過性のあるビュー層」を実現する

Page 35: Flux react現状確認会

Reactのテンプレートの書き方• JSで React.DOM.Div() みたいな関数を使って頑張って組む

• またはJSX (JavaScript XML)で組む

• XMLリテラルぽいが、最終的にプレーンなJSの関数に落とし込まれる

Page 36: Flux react現状確認会

JSX Example (変換前)

Page 37: Flux react現状確認会

JSX Example (変換後)

Page 38: Flux react現状確認会

ReactとFlux

• Store->Viewへの変更通知を簡略化できる

• Reactでは変更後のデータ一式全てを受けても描画コストを抑えられる

• 他ライブラリでは、丁寧に差分情報を作る必要が有る

Page 39: Flux react現状確認会

Reactのテスト• 公式には「これを使え」というモノは無い

• ただしJest(読み込んだものを全部モックにする)というものを公式が超pushしてる

Page 40: Flux react現状確認会

Reactのデメリット• React自身が未だ0.xの状態(バージョンアップ時に破壊的変更の可能性)

• 枯れてはいない

• React管理下のDOMツリーに対して、他のライブラリを当てるのは面倒くさそう

Page 41: Flux react現状確認会

なぜReactに飛び移ったのか

Page 42: Flux react現状確認会

色々あった

Page 43: Flux react現状確認会

Reactを選んだ理由• 参照透過性のあるビュー = 状態予測可能性が高い

• APIレベルでデータの値と状態を分離している

• JSXテンプレートがプログラマブル (積極的に使いたくは無いけど)

• ドキュメントが良い

(開発元のFacebook自身が使ってる)

Page 44: Flux react現状確認会

ReactでFluxを実践した現状

Page 45: Flux react現状確認会

1. Store -> Viewの更新通知• オリジナル

通知を受けたらStoreから、getterメソッドで取得してる

• 弊プロジェクト「そんなことはしない。通知時に一緒にデータ全部を渡す. StoreとViewを疎に.」

Page 46: Flux react現状確認会

2. Actionの更新通知• オリジナル

リクエスト失敗ケースを考えると、APIリクエストもAction起因に

• 弊プロジェクト

APIリクエストはStoreの領分なのと、 サーバーは永続ストレージという認識なので、Storeに詰め込んだ

Page 47: Flux react現状確認会

3. テスト• オリジナル

「Jestでモックすれば楽!」

• 弊プロジェクト

「モックは実装に立ち入り過ぎ. 静的にできる範囲で, mochaとpower-assertで.」

Page 48: Flux react現状確認会

4. Viewのテスト• イベントハンドラの無いViewにユニットテストは必要ないと判断

• イベントハンドラのテストはしたい

• E2Eテストでカバーも考えたい

• ほとんどが未着手・検討中

Page 49: Flux react現状確認会

まとめ• 常に気をつけてMVCをやりたくはなかった

→Fluxを採用した

• Viewの更新を楽にしたいし,

デバッグもなるべく楽にしたかった→Reactを採用した

• ReactはView操作のパラダイムシフト

Page 50: Flux react現状確認会

会場でのQ&Aとか議論とかまとめ

Page 51: Flux react現状確認会

Q. Store内部の依存関係の解決は?

• Dispatcherが処理順序解決の方法を持っているのでそれに頼る(実装依存)

• 無かったらメッセージの種類を増やして頑張るしかなさそう

Page 52: Flux react現状確認会

Q. ユーザーの入力が複数起きたら?

• Fluxの本義に従えば、毎回データフローを回るべきだし、それで十分に回ると思う

• 万が一回らなくなったら、そのとき考える

Page 53: Flux react現状確認会

Q. 「5件メッセージがキューに溜まったら更新したい」場合は、どうする?

• Store側で適切に閾値を決めて、Viewへの通知回数を管理すれば良いのでは

Page 54: Flux react現状確認会

Q. jQueryプラグインなどと併せて使いたい(React移行中のケースなど)

•その話は止めろ

Page 55: Flux react現状確認会

Q. どうしてもjQueryプラグインなどと併せて使いたい

•そんな事を考えてはいけない

Page 56: Flux react現状確認会

Q. やっぱりjQueryプラグインなどと併せて使いたい•本当にそのjQueryプラグインが必要なのか胸に手を当てて考え直して、やっぱり必要だったらReactで書き直すしかない

Page 57: Flux react現状確認会

Q. Reactに書き直している暇はないんだけど、止むに止まれぬビジネス上の緊急を要する都合により早急にこのjQueryプラグインを使わなければ死人が出る可能性も十分にありえる状況において、どうにかしてReactによって統治されたサブツリー内でjQueryプラグインを使う方法はありますか?

• getDOMNode()で生のDOMに触れる + shouldComponentUpdate()を応用して, jQuery適用対象のDOMをReactに更新させなければ、なんとかいける、はず(やったことないので根拠はない)

Page 58: Flux react現状確認会

Q. アニメーションとかどうする?

• ReactがReactCSSTransitionGroupというものを持っているので、これで対応できるはず

• メチャクチャ複雑なことやりたい場合については、まだ体験した事が無いのでよくわからん

• 「絶対に更新されないComponent」を作ればいいんじゃないの?

Page 59: Flux react現状確認会

Q. JSXの名前解決とか

• 普通のJSの関数呼び出しに変換されるので、普通のJSと一緒と考えて良い

• React Componentのメンバ関数のthisは,

各インスタンスにbindされる

Page 60: Flux react現状確認会

Q. Virtual DOMの差分情報は取れる?• ReactにPublicなAPIとしては現在存在しない

• 欲しければ, Matt-Esch/virtual-domを使おう

Page 61: Flux react現状確認会

Q. サーバーサイドでプリレンダリングしたものにReact当て込みたい

• やったことがないのでわからない

• API的には出来そうに思えるけど???

Page 62: Flux react現状確認会

Q. Reactの差分描画は最速?

• DOM職人には勝てないと思う

• 職人エンジニアだけでチームを組まずとも、生産性を維持しつつ「けっこう速い」ものを開発するためのツールと割り切るべきでは