Upgrade to Pro — share decks privately, control downloads, hide ads and more …

導入して1年経ったReact周辺の 技術スタックを反省します | React反省会@Wantedly

導入して1年経ったReact周辺の 技術スタックを反省します | React反省会@Wantedly

React反省会@Wantedly 2017/05/10

Kento Moriwaki

May 10, 2017
Tweet

More Decks by Kento Moriwaki

Other Decks in Programming

Transcript

  1. React反省会@Wantedly
    導入して1年経ったReact周辺の
    技術スタックを反省します
    Kento Moriwaki / 森脇健斗

    View full-size slide

  2. シゴトでココロオドル
    シゴトでココロオドル
    Reactを導入してから1年3ヶ月
    経ちました
    2

    View full-size slide

  3. シゴトでココロオドル
    • 導入方法
    – 何を考えて、それはうまくいったか
    • 技術スタックの選択
    – 導入時に考えたこと
    – 反省点
    – 改善アイデア
    • 話さないこと
    – React自体と他のframeworkとの比較
    話したいこと
    3

    View full-size slide

  4. シゴトでココロオドル
    • Kento Moriwaki
    • Wantedlyのエンジニア
    • 新卒入社して3年目
    • 主にRailsとReact
    • Feed team &
    International team
    自己紹介
    4

    View full-size slide

  5. シゴトでココロオドル
    • jquery-ujs
    • Backbone
    • Angular 1
    • React
    – 今ここ
    – 2016/02から1年3ヶ月
    Wantedlyのフロントの歴史
    5

    View full-size slide

  6. シゴトでココロオドル
    • 一気に全体に導入された
    • 詳しい人は一人だけ
    – コードレビューもほとんどできない
    – あまり良くないコードが堂々としている
    • みんな書きたがらない
    – 学習コストが高い
    – 勉強する余裕がない
    – とりあえずjQueryでなんとかすればいいか
    まずはAngular 1を反省
    6

    View full-size slide

  7. シゴトでココロオドル
    • 書く人を増やすことに尽力した
    – 社内勉強会を何回も開催した
    • みんな興味はあるのでちゃんと聞いてくれた
    – Reactいいよ、と呟く
    • 一部から導入した
    – 独立した機能から導入した
    – 新機能やリニューアル時に少しずつ増やしていった
    • デザイナーに認めてもらう
    – 前回Reactで作ったのが良かったから、次もあのクオリティに
    したい
    – React前提でデザインが進められる
    React導入時に注意したこと
    7

    View full-size slide

  8. シゴトでココロオドル
    • React書く人増えてる
    – 自分のチームは全員書く
    – ほぼ全てのチームで導入されている
    • 10機能で使用されている
    • Component数は約300
    その結果
    8
    よかった!

    View full-size slide

  9. シゴトでココロオドル
    シゴトでココロオドル
    いい話はここらへんにしておいて
    9

    View full-size slide

  10. シゴトでココロオドル
    • React入れるには、他に色々判断しないといけない
    – 言語は?
    – どうやってビルドする?
    – Flux?
    – Styleは?
    – ディレクトリ構成は?
    – テストは?
    • 導入当時の選択を振り返って、反省したい
    React周辺の技術スタック
    10

    View full-size slide

  11. シゴトでココロオドル
    • Tool
    – webpack, Babel, ESLint
    • Library
    – Redux, Redux-thunk, Immutable.js
    – CSSModules, react-css-modules
    • Other
    – flux, E2E test
    今の主な技術stack
    11

    View full-size slide

  12. シゴトでココロオドル
    Tools
    12

    View full-size slide

  13. シゴトでココロオドル
    • Railsからは切り離し、webpackを使っている
    – webpack-dev-server すごく便利
    • 完全なSPAではない
    • 独立した機能から使い出して、独立したアプリケーション
    がいっぱいできた
    – Entryファイルが機能ごとに分かれている
    • いざ全体にReactを入れていこうと思ったら、結構困った
    (困っている)
    webpack
    13

    View full-size slide

  14. シゴトでココロオドル
    webpack
    14
    • 各機能が独立しているので、一
    緒に読み込めない
    • リンク一つで遷移できるはずな
    のに、ページのフルリロードが必

    manage_posts.js
    analytics.js
    tickets.js
    messages.js

    View full-size slide

  15. シゴトでココロオドル
    • こういうファイルが何個もある
    – それぞれがstoreを作って、routingしてる
    • まとめるのはかなり大変
    webpack
    15
    const store = configureStore();
    const history = syncHistoryWithStore(browserHistory, store);
    ReactDOM.render(


    path='/enterprise/analytics'
    component={AnalyticsContainer}
    >




    ,
    document.querySelector('[react-component=EnterpriseAnalyticsContainer]'),
    );

    View full-size slide

  16. シゴトでココロオドル
    • 反省: アプリケーションは一つで、lazy loadで必要なも
    のだけ呼ぶようにする
    • webpackのdynamic importでできる
    – ComponentやActionだけじゃなく、reducerもreplaceで
    きる
    • Storeやroutingの設定は一つになるように
    • 全体は一つのアプリケーションで、必要なページで追加の
    コードが読まれるように
    webpack
    16

    View full-size slide

  17. シゴトでココロオドル
    • もともと入れてなかった
    – Ruby側で使っていなかったから
    • すごいペースでコードが汚くなっていく
    – 使ってないのにimport
    – 中途半端なpropTypes
    – `==` vs `===`
    – 人間の目ではレビューしきれない
    • 途中から導入することに
    • 詳しくはこちらに
    – 全力で大きくなるReactのコードをスタイルガイドに沿って見直したら、大変勉強に
    なりました | Wantedly Engineer Blog
    ESLint
    17

    View full-size slide

  18. シゴトでココロオドル
    • 反省: 初めから入れて、徹底しよう
    • JSのコードは汚くなるもの
    • エディタでチェックするようにメンバーで共通する
    • レビューでは気づけないので、CIに入れてもいいかも
    • 厳しめに入れて、後から緩くすればいい
    ESLint
    18

    View full-size slide

  19. シゴトでココロオドル
    Library
    19

    View full-size slide

  20. シゴトでココロオドル
    • Immutable便利
    – Immutable.Recordでビジネスロジックを持ったオブジェ
    クトを作れる
    – OrderedSetなどのデータ構造もよく使う
    • どこはImmutableで、どこはPlainなのか
    – ReducerごとのstateはPlain
    – EntityをImmutableでつくる
    – が、徹底して統一するのは難しい
    Immutable.js
    20

    View full-size slide

  21. シゴトでココロオドル
    • このオブジェクトは、Immutable?
    • この配列はArray or Immutable.List ?
    • propTypesも適当になってくる
    – anyがいっぱい
    • どちらかに統一するというよりは、型が分か
    れば解決できる問題
    – TypeScriptとかなら解決できる
    Immutable.js
    21

    View full-size slide

  22. シゴトでココロオドル
    • 状態管理を行うcomponent
    – 主にReduxとconnectするcomponent
    • どこからContainerで、どこからComponentにするか
    – ページ単位?
    – Routing単位?
    – 実はどこでもいい
    Container(Redux)
    22

    View full-size slide

  23. シゴトでココロオドル
    • Containerは一番外側のcomponent、みたいに思って
    いたおかげで、propsの受け渡しが多すぎるひどいコード
    が増えた
    • すごく雑なpropTypesや、全部受け取るconnectの出
    来上がり
    Container
    23
    export default connect(
    state => ({
    analytics: state.analytics,
    }),
    dispatch => bindActionCreators({
    ...actions
    }),
    )(AnalyticsContainer);

    View full-size slide

  24. シゴトでココロオドル
    • もっと細かくContainerを分けるべき
    – 必要ないstateも受けていると、パフォーマンスが
    下がる
    – 受け渡すだけのprosは、可読性も下がるし、書く
    のもかなり面倒さい
    • ディレクトリ構成も一因に
    – Componentから遠いので、行き来するが面倒
    – `import from ‘../../../containers/’;`
    Container
    24

    View full-size slide

  25. シゴトでココロオドル
    Language
    25

    View full-size slide

  26. シゴトでココロオドル
    • ES2015をbabelでトランスパイルしている
    • Stage-3まで使える
    – Candidateなので、大きく変わる可能性は小さい
    • それ以下は要相談
    – `static propTypes =` などは使っている
    – simpleで変わる心配少ない & 変わっても簡単に直せ
    る & 可読性がかなり上がる
    – TypeScriptでもかけるし。。
    ES2015
    26

    View full-size slide

  27. シゴトでココロオドル
    • 型は必要だった?
    – Railsを書いている人が大部分なので、ハードル
    が高いと思った
    • CoffeeScriptからの差が大きい
    – 今はgolangとか書く人も増えてるし、型の良さも
    共通認識である(と思う)
    – TypeScriptのIntelliSenseがいい
    ES2015
    27

    View full-size slide

  28. シゴトでココロオドル
    • 反省: TypeScriptにしても良かった
    – propTypesも標準じゃなくなるし
    – Googleでも標準言語になってるし
    – VS Codeで生産性高いし
    • 途中からTypeScriptにするのは骨が折れ
    そうだから、初めからTSにできるならした方
    がいい
    • Flowでも可
    ES2015
    28

    View full-size slide

  29. シゴトでココロオドル
    Test
    29

    View full-size slide

  30. シゴトでココロオドル
    • 現:JSの単体テストはなく、Railsも含めたE2Eテストで担
    保している
    • Wantedlyのwebエンジニアは、フロントもサーバーも一
    人で書く場合が多い
    – バーっと動くものをつくって、重要なところをE2Eで担保
    していくスタイルがあっていた
    • Angular時代も単体テストを書く環境はあったが、ほとん
    ど書かれることはなかった
    テスト
    30

    View full-size slide

  31. シゴトでココロオドル
    • 反省: テストはかけた方がいい
    • 全てE2Eテストを書くのは大変
    • 各Component書く必要はなさそう
    • ActionCreatorや、ビジネスロジックはテス
    トが書かれるべき <- 当たり前
    • 環境整えるのが大変なので、誰か助けてくだ
    さい
    テスト
    31

    View full-size slide

  32. シゴトでココロオドル
    Directory Structure
    32

    View full-size slide

  33. シゴトでココロオドル
    • react/
    – components/
    • {fooapp, barapp}/
    – containers/
    • {fooapp, barapp}
    – reducers/
    • {fooapp, barapp}
    – actions/
    • {fooapp, barapp}
    – lib/immutable/
    ディレクトリ構成
    33
    • 外側は役割ごとに分けられて
    いる
    • その中は、機能ごとに同じよう
    に分けている
    • 実際はもうちょっと汚い
    • 初めはflatだった
    • 一つの機能が離れたところに

    View full-size slide

  34. シゴトでココロオドル
    • StateとUIを分けるべき
    – アプリケーションの状態とUIのReactとは切り離す
    – ComponentsとContainerはディレクトリで分けなく
    ても良さそう
    • 関心ごとにまとめるべき
    – 一つの機能に関するコードを近くに集めることで、
    データの流れが追いやすくなる
    • 参考
    – Automattic/wp-calypso
    ディレクトリ構成
    34

    View full-size slide

  35. シゴトでココロオドル
    • components/
    – {fooapp, barapp}/
    • Baz.jsx
    • BazContainer.js
    • state/
    – {fooapp, barapp}/
    • action.js
    • reducer.js
    • selector.js
    • models/
    ディレクトリ構成[理想]
    35

    View full-size slide

  36. シゴトでココロオドル
    Others
    36

    View full-size slide

  37. シゴトでココロオドル
    • CSSModulesを使っていた
    – CSSが分かれていて、デザイナーでも触りやすい
    – Rails側でscssを使っているので、変数の共有な
    どのために統一した
    • react-css-modules
    – className={style.tabel}
    – styleName=’table’
    – 書く量が減って、いいかなと思った
    CSS
    37

    View full-size slide

  38. シゴトでココロオドル
    • react-css-modulesのパフォーマンス
    – 実行時の解決なので、コストがかかる
    • babel-plugin-react-css-modules
    – BabelのCompile時に解決してくれるのでパフォー
    マンスがいい
    – 何が起きてるかわかりにくいbabelのpluginは入れ
    たくない
    • 学習コストが上がる
    • なんでもできちゃう
    CSS
    38

    View full-size slide

  39. シゴトでココロオドル
    • シンプルにCSSModulesだけで良かった
    • className={s.table}って書くだけで、大し
    て面倒ではない
    – 直感的に理解できる
    – undefinedチェックとか実装時はうざいだけ <= 設
    定の問題
    – camelCaseのスタイルでもいいじゃん
    CSS
    39

    View full-size slide

  40. シゴトでココロオドル
    • State treeからデータを取ってくる関数
    – 離れた場所のデータを組みわせて使いたい場面
    とかに便利
    – redux/reselect を使うとメモ化なども行なってくれ、
    パフォーマンスにも優しい
    • 初めは、render内で毎回計算したり、state
    に保存したりしていた
    Selector
    40

    View full-size slide

  41. シゴトでココロオドル
    • state treeの構造をどうするべきか
    – APIのデータをそのままstateに入れると、nestが
    深くなる
    – 深いデータが更新されると、上側も全て更新され

    – パフォーマンス的にもよろしくない
    – データの一貫性を保つのが難しい
    • Reducerのコードが複雑になる
    Normalize
    41

    View full-size slide

  42. シゴトでココロオドル
    • 各entityごとにnestを均してから保存する
    – IDをkey, entityをvalueにしたMapに保存
    – 元あった場所にはIDを入れておく
    – propsはIDを渡して、connectでentityを取ってくる
    • 利点
    – 関係ないデータが変更されても、updateが少なく
    なる
    – Reducerの処理がシンプルになる
    • IDからデータを探して更新するだけ
    Normalize
    42

    View full-size slide

  43. シゴトでココロオドル
    • Reduxのmiddleware
    – Actionのdispatchに割り込んで、色々できる
    • 非同期処理を扱うために、redux-thunkだ
    け入れた
    – Simpleでとにかく学習コストが低い
    • Loggingなどの副作用や、共有化された
    APIコールなどで、適宜作っている
    • こういうところに単体テストがないの良くない
    middleware
    43

    View full-size slide

  44. シゴトでココロオドル
    まとめ
    44

    View full-size slide

  45. シゴトでココロオドル
    • React導入一年経って、うまくいっていると胸
    を張って言える
    • チームの状況を見てスタックを選択しよう
    – Wantedlyは一人がサーバーとフロントを両方書く
    体制
    • 大きな失敗はないけど、もっとよくできたと反
    省は絶えない
    • これから導入する人の参考になれば嬉しい
    まとめ
    45

    View full-size slide

  46. シゴトでココロオドル
    We are hiring!
    46
    https://www.wantedly.com/projects/59809

    View full-size slide