【メモ】React.js meetup #4 2016/9/27 @サイボウズ株式会社
これに行ってきたのでそのメモ。
React.js meetup #4
Reactですよ
まさかSPAを語り尽くす会から引き続いてこちらも抽選当たるとは思ってなかったけれどラッキーなことに当たったので行ってきました。
そして全力でメモしてきました。
目次
- Graph API: GraphQL and Falcor
- 複雑なJavaScriptアプリケーションを考えながら作る話
- Should I use redux-saga or not?
- Real World React2
- ReactコンポーネントとCSSコンポーネントは1対1なのか問題について
- ReactとGoogle Analytics
- reduxを使わずにreact+railsする
- Jest
本編
残しといたメモを貼りつつ感想を付け加えていくスタイルで。
Graph API: GraphQL and Falcor
@Quramyさん
内容
GraphQLやFalcorの目的
一つのサービスに対して複数のクライアントがAPI接続してくるようなシステムを効率よく開発したい
githubの最近starしたrepositoryを取得する例
従来 => まずはユーザー情報を取得してからそのユーザーを元にstarを取得する
希望 => 2回リクエスト送るのはめんどいからユーザー情報とってきた時点でstarしたrepositoryも一緒にほしい
ならば最初からほしいやつを言え => それがGraphQLとかFalcor
「欲しい情報をほしい分だけ」っていうこの仕組み -> Demand Driven Architecture (以下DDA)
GraphQL
- facebook社作のクエリ言語
- 2015年オープンソース化
2016年にproduction ready
データの検索や操作にはqueryを利用する
- ほしいものを書けば一気にとってくれる
- イメージとしては独自のSQL
- 独自のSchema Systemが備わっている
React and GraphQL
- Relay
react-apollo (Meteorが開発した)
Relay Architectureはfluxライクな感じ(公式サイトに画像あり)
- RelayコンテナでReact Componentをラップする(reduxのconnectっぽい)
- コンポーネントとクエリをペアで作る
- 最終的に一つのクエリにまとまる
Caution
- GraphQLのserverがある != Relayから接続できる
- GraphQL Relay Specを実装する必要がある(cache管理やPagingのため)
Falcor
- netflixが開発
- まだDeveloper preview
One Model Everywhere
- クラサバ間でグラフ構造を共有しましょう
- 必要なパラメータを列挙したらそれに応じたデータがもらえる
内部でJSON Graphというデータ形式でCacheを構築する。JSON Graphは参照をクラサバで共有するための仕組み。
- Falcorが扱うデータは正規化されている
- One Fact in One Place
- normalizrと似てる
React and Falcor
Falcorはviewには依存していない(modelのみを担当する)。
componentDidMountでmodelを監視するイベントを設置するみたいなやり方がある。
Other Resources
- falcorjs-and-react netflixの中の人がつくったやつ
- redux-falcor
DDA for Front-end
- フロントの都合に合わせてAPIをリクエストできる
- データの正規化も面倒みてくれる
しかし
- サーバ側に押し付けているのでは?
- データの結合関係を決められない(SQLに頼りにくい)
- 容易にN + 1問題が発生する。性能を担保できるのか
(dataloaderなどのcaching/batching libraryを用いて負荷の低減は可能)
ほんとにDDAは必要か?
向いてるやつ
- 複数のクライアントを考えてる
- 通信料を絞り込みたい
- データ構造に多対多が頻出する
向いてないやつ
- デスクトップメイン
- 自社のクライアントから呼べれば良い
- 木構造が扱えれば十分なもの
まとめ
DDAがほんとに必要かはしっかり考えてからGraphQLやFalcorを導入すべき
感想
GraphQLとFalcorに関しては、Relayを初めて知ったときに触ってはみたものの、そのときに使ったサンプルが全く動かせず、解決できずで断念した記憶があった。
そこからちょいちょい名前は聞いていたが全然深堀りせずに今に至るわけだが今日話を聞いた限りだと上手くはまれば便利にはなりそうだが、それがはまるパターンがそんなに多くなさそうっていう印象。
クライアントで気持ち良くなるためにGraphQLをやりたいがためにサーバーで頑張ったりクラサバ間にまた一個レイヤー作ったりとか、涙を流さずにはいられない努力が必要になりそう。
でもとても気持ち良くはなりそうなので一回勉強してなんか作ります!
複雑なJavaScriptアプリケーションを考えながら作る話
@azu_reさん
複雑なJavaScriptアプリケーションを考えながら作る話
内容
前提
- 作成するアプリケーションによって必要な構造は違う
- SSRはしない
Almin.jsを作ったという話
目的
- 難しいものは考えてつくるしかない
- 構造かすることでメンテナンス性を高める
構造化の目的
- 属人性が高くならないようにする
fluxのデータフロー
fluxの見方をかえる
ドメインモデルを作る目的は切り分け
fluxの曖昧なところ
- ドメインレイヤーが曖昧
ショッピングカートの例
storeが曖昧になる。
商品の一覧とカート(ProductSore, CartStore)。
CartStoreからカートのstateをとれる。CartStoreはProductStoreに依存している。 => storeは独立させると問題がおきる。
- Reduxはsingle storeなので問題はない
fluxだとwaitForでdispatchされたActionの順番を明示できるから問題ない
掛け算じゃなくて足し算にしたい -> CQRS(コマンドクエリ責務分離)
- WriteとReadを明確にわける
=> Storeが色々やってるのでわけづらい
Almin.jsを作った話
- Write * ReadをWrite + Readに(アプリケーションの構造によって掛け算の方がいいこともある)
- ドメインモデルを扱える構造を作る
- start from the use cases(UseCase => アクターがシステムに対して何をしたいのか)
- モデル自身は自分の永続化に関心がないってのが良い方法
- Repositoryがドメインモデルのインスタンスを永続化する
情報量が多すぎてここらへんからメモを取ることを諦めたのであとは資料を読んでくれれば。
というか本当に深い内容なので是非ちゃんとみんな読んでほしい。
ここに全部書いてある => Introduction · Almin.js
感想
凄まじい情報量でした。
これはあとでじっくり全部の資料読み込んで実践しなきゃってなるやつでした。早く帰ってやりてえって気持ちがとても高まった。
これだけでも本当に来てよかったと思う内容でした。
Should I use redux-saga or not?
@kuyさん
内容
redux-sagaの話
- reduxのmiddleware
- reactにもreduxにも書きたくないコードをおく場所を提供
- yieldによって非同期処理を同期処理として書ける
- 副作用をデータとして扱える
登場人物
- saga 実行したい処理をまとめたプロセスのようなもの
- effect データとしての副作用
- saga runtime 実行環境
effectを使って処理を書く。
- call: Promiseの完了を待つ
- select: Stateから必要なデータを取り出す
- put: Actionをdispatchする
- take: Actionを待つ、イベントの発生を待つ
- fork: 別のタスクを開始する
- cancel: タスクを終了する
saga rauntimeの中でeffectを実行する。
redux-sagaのコードが増えてきたら
- 適切に分割する
- 単一責務を意識する
- actionを受け取ったら別のactionをdispatchして画面遷移する => actionをチェインさせるsagaとactionを受け取ったら画面遷移するsagaを独立して動作させる
- 共通のsagaを切り出す
- 変化の少ないソリッドな処理はmiddlewareで書く(Socket.IOとの連携など)
redux-sagaの問題点
- 初見殺し
- generator/yieldが必須(regeneratorRuntimeによってスタックトレースが死ぬ)
- dispatchされたActionをrejectできない(reducerの後ろにあるので)
side effect middlewareに求めているもの
- scalability + composability
- testability
- background/long-running process(UIコードと完全分離したい)
redux-sagaよりいいものは -> redux-logic???
redux-logicとは
- middlewareを構造化してくれる、内部はRxJS
- 副作用コードをvalidate,transform,processの3つに分ける
- サービスがDIされるのでテストは比較的しやすい(モックは避けられない…?)
まあ他にも今さらに色々出てきているよ。
まとめ
middleware戦争は収束の見込み無しなので、本当に必要なものを見極めて使っていくべき。
感想
僕はReact + Reduxのアプリケーションを業務で書いていてそこでredux-sagaを使っているので、うんうん言いながら聞いていたが、確かにredux-sagaはgeneratorとかyeildとか使ってるし、while(true)とかやっちゃったりするし、初見だと相当気持ち悪さを感じるかもしれないけれど、ここまで責務を分けていると本当にどこに何を書くべきかがわかりやすくてとてもやりやすい、と思っている。
そんなわけでわりと満足してしまって最近にredux middlewareの話を追いかけていなかったけれど、そんな間にまた相当でてきたみたい。
そっちも今度試してみよう。
Real World React2
@mizchiさん
内容
いかにReactをふつうのwebアプリに導入していくかという話。
普通のwebアプリとは
- SPAではない
- SPAでなくてもReactは使える
- jQueryに支配された現代のフロントエンドを改善したい
- 複雑なモジュールを局所的に解決するのにReactが有用である事を示したい
フロントの流れ
(次は仮想DOMの隠蔽が来そう)JSXに縛られる状況の改善とか
Reactの難しさ
- エコシステム構築 <= ここを解決する
- flux概念
- (React自体は難しくない)
Reactが乗るためのモダンJS
- npm/browserify or webpack
- babel/es2015
- react/flux
- testable
- no more jquery plugins
- no side effect on module loaded(importした時点で副作用が発生するようなモジュールが多い。関数を返すべきである)
なんかよくする
- モダンな開発環境を導入する
- 再利用するコードとできないコードを分別する
失敗。
- 仕様を理解してないもののコードは書けない
- モジュールの境界面が明示されていないものは分解できない
- 「別実装で実装を完全に再現」は無理
ゴールの設定
- React/babelで新規モジュールを受け入れられる環境
- turbolinks(PushState)が導入可能な初期化フローを作る(使うかはともかく)
Reactのテストはenzymeをつかう
とりあえずこれ使っとけばok
flowtypeの導入理由
- 段階的に導入できる
- reactのpropsに対して型がきく
- 推論が優秀
最終的に
今は最初に失敗したQiitaの編集画面のリファクタに戻ってきた。がんばる。
感想
これ今年の頭に参加したJSer.info 5周年記念イベントで話してたのと同じやつだあと思ってたら本当に同じやつだった。
ただそのときから内容がアップデートされていた。
@mizchiさんほどのエンジニアでも失敗を繰り返して泥臭く奮闘をしているその圧倒的現実感に胸を打たれつつ、こういう夢物語ではないReact話をもっと聞いて勇気をもらいたいとそう思ったのでした。
そしてQiitaとかでも仕様書なしに進めていくんだなあ…しみじみ。って感じでした。
これ以降はピザ食べながらのLTタイム。
ピザ食べてたのでメモできなかったり中途半端だったりするけれどご了承ください。
ReactコンポーネントとCSSコンポーネントは1対1なのか問題について
@shibe97さん
内容
1対1派の話。以前は1対1ではない派だった。
React ComponentとCSS Component
React ComponentはHTMLのまとまり、CSS ComponentはCSSのまとまり。
CSSはHTMLに紐づく。 => つまり1対1
browserify/webpackによって分割ができるようになったため、CSSと同じ粒度に揃えることができる。
極端な話、DOMの一つ一つがcomponentになりうる。
ベストはAtom単位(atomic design)でComponent化。
現実的には工数の問題もあるので、徐々にComponent化していく。
超ちっちゃい単位でもコンポーネント化する意味はある
- スタイル込みのComponentにできる
- 他のComponentに流用できる
CSS Componentの難しいところ
- コンポーネント内にスタイルは閉じている必要がある
- 外部に影響を与えるスタイルは外側で定義
各Componentに必要なこと
- 自分自身のスタイリング
- 子Componentのレイアウト
これはReactと同じ => つまりReact Componentと粒度は揃う
まとめ
感想
ここ最近でわりと熱い話題。この話題になるといつも言っちゃうけど、僕は以前にこの記事を見てから完全にそれに共感してしまっている立場。
しかしスライドを見ていて、理想論をつきつめると確かにそうだなあーと同意できる話だった。
しかし現実問題として、ここで話されているレベルのComponentの細分化は無理だと思うのでやっぱり僕はCSS in JSは現状はしないで実装していくかなあーっていう。
もちろん無理というのは工数的な話なので趣味開発では@shibe97さんの言うやり方でやってみたいなと思った。
ReactとGoogle Analytics
内容
reactアプリケーションのアクセス解析について
- react-gaとかのComponentがいまいち
- 従来通りheaderに埋め込むのか?
- Componentを使うのか?
結局Componentもscriptタグがappendchildされる。
初期化タイミングが遅くなる。
reactアプリ外からsendするときはだめ。
=> コンポーネントは良いことが特にない
アプリ内のどこにsendするコードを書くのか
画面表示用コンポーネントに書いてはだめ => まったく同じComponentインスタンスが再利用されるときとかあるから
正解 => routingポイントでsendする(react-routerとか)
react-router-reduxのreadmeでhistory.listenってのがあるけど…
pathnameってのがコールバックに渡ってくるけれど、それだとURLにIDが入っちゃって同一ページでもばらけてよくわからない。
react-routerのonEnterフック => pathという情報がとても有用。これを使うと良い感じになる
まとめ
- コンポーネントでやると微妙
- react-routerからsend pageviewすると良い感じ
感想
僕はまだSPAやってるときにGAを使う状況になってなかったので全く未経験の話だったがこれは覚えておくとあとあととても役に立ちそうだなと思った。
こういう現実的なsolutionはgladな感じです!
reduxを使わずにreact+railsする
内容
※ピザに夢中でしたすみません。
感想
1ページ1コンポーネントで運用しているという話には「なん…だと…」っていう感想を持った。
Jest
@cpojerさん
資料は見つからないので見つかり次第載せます。(多分見つからない)
内容
Jestというテストフレームワークの話。
facebookからやってきてくれたらしい!
- Jestは複数のworkerでテストを動かす
- とても早い
npm install -D jest babel-jest
- enzyme使ってるならJest使うべし
- toMatchSnapshot() => UIのdiffがとてもわかりやすい
- カバレッジの仕組みもある
感想
英語聞き取れません…。つらい…。
僕がわかったのはこの程度です…。ふえええ…。
とりあえずとても良さそうというのはわかった。painlessとはなんとも素敵な響き。
その前にクライアントのテストを書いてないのでまず僕はそこからしっかりやらねばならない。テスト書くぞ!
まとめ
とても熱い一日だった。
特に@azu_reさんのスライドはとても気合が入るというかモチベーション上がる話だったのでしっかり資料読み込んで学ぼうという気持ちになった。
なんかもはやReactの話が前のように「Reactはいいぞ」一辺倒ではなくてしっかり現実と戦う感じの話が多くなってきたのが聞いていてためになる感じで良い。
@mizchiさんの話とかは今年頭からのアップデートって感じで1年を感じられた気がしたのもまたおつでした。
そしてピザがひたすらおいしかった。ピザがくると話を聞く力が1/5くらいになっちゃうのがちょっと困ってしまう。
そして最近は発表者が何を使って発表してるかってのを観察しているのだけれどやっぱりもはやslideshareは本当に少なくて、サービスとしてはspeaker deckの方が使われてる。そんでその上をいくのがHTMLベースで自分のサーバーに置くパターンだった。
僕も今まではspeaker deck使っていたけれどgithub pagesとかで管理していきたい。
やっぱり@mizchiさんはQiitaスライドだった。Qiitaスライドはこれからどんどん増えていきそうな気配。あーでもスライドだとフォントサイズで困っちゃうっていうパターンを何度か見てるからそこはネックかもしれない。
とにかく今日は熱い一日だったので明日からも頑張っていこう。
でもその前にペルソナ5を終わらせたい。