Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
導入して1年経ったReact周辺の 技術スタックを反省します | React反省会@Wantedly
Search
Kento Moriwaki
May 10, 2017
Programming
10
8.5k
導入して1年経ったReact周辺の 技術スタックを反省します | React反省会@Wantedly
React反省会@Wantedly 2017/05/10
Kento Moriwaki
May 10, 2017
Tweet
Share
More Decks by Kento Moriwaki
See All by Kento Moriwaki
わかった気になれる CRDT を使った共同編集
kentomoriwaki
5
3.6k
デザインシステムを導入してUIに秩序を取り戻す - React (Native)編 #rejectron2018
kentomoriwaki
16
3.5k
ReactでWebとNativeの共通UIライブラリを作ろう
kentomoriwaki
0
1.1k
BFFを導入しなかった理由
kentomoriwaki
4
13k
TypeScript in Wantedly
kentomoriwaki
2
660
5分でわかる React "Suspense"
kentomoriwaki
3
1.4k
Immutable.jsとReact @Wantedly ~入門編~
kentomoriwaki
8
74k
React速習会@Wantedly
kentomoriwaki
1
400
Other Decks in Programming
See All in Programming
OpenTelemetryでRailsのパフォーマンス分析を始めてみよう(KoR2024)
ymtdzzz
4
1.6k
PHP でアセンブリ言語のように書く技術
memory1994
PRO
1
150
Kotlin2でdataクラスの copyメソッドを禁止する/Data class copy function to have the same visibility as constructor
eichisanden
1
140
詳細解説! ArrayListの仕組みと実装
yujisoftware
0
480
Vue SFCのtemplateでTypeScriptの型を活用しよう
tsukkee
3
1.5k
NSOutlineView何もわからん:( 前編 / I Don't Understand About NSOutlineView :( Pt. 1
usagimaru
0
150
RailsのPull requestsのレビューの時に私が考えていること
yahonda
5
1.7k
Realtime API 入門
riofujimon
0
110
Vitest Browser Mode への期待 / Vitest Browser Mode
odanado
PRO
2
1.7k
Streams APIとTCPフロー制御 / Web Streams API and TCP flow control
tasshi
1
290
CSC509 Lecture 09
javiergs
PRO
0
110
WEBエンジニア向けAI活用入門
sutetotanuki
0
300
Featured
See All Featured
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
43
6.6k
Navigating Team Friction
lara
183
14k
Speed Design
sergeychernyshev
24
570
Product Roadmaps are Hard
iamctodd
PRO
48
10k
KATA
mclloyd
29
13k
Music & Morning Musume
bryan
46
6.1k
StorybookのUI Testing Handbookを読んだ
zakiyama
26
5.2k
Git: the NoSQL Database
bkeepers
PRO
425
64k
10 Git Anti Patterns You Should be Aware of
lemiorhan
654
59k
Building Flexible Design Systems
yeseniaperezcruz
327
38k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
250
21k
Documentation Writing (for coders)
carmenintech
65
4.4k
Transcript
React反省会@Wantedly 導入して1年経ったReact周辺の 技術スタックを反省します Kento Moriwaki / 森脇健斗
シゴトでココロオドル シゴトでココロオドル Reactを導入してから1年3ヶ月 経ちました 2
シゴトでココロオドル • 導入方法 – 何を考えて、それはうまくいったか • 技術スタックの選択 – 導入時に考えたこと –
反省点 – 改善アイデア • 話さないこと – React自体と他のframeworkとの比較 話したいこと 3
シゴトでココロオドル • Kento Moriwaki • Wantedlyのエンジニア • 新卒入社して3年目 • 主にRailsとReact
• Feed team & International team 自己紹介 4
シゴトでココロオドル • jquery-ujs • Backbone • Angular 1 • React
– 今ここ – 2016/02から1年3ヶ月 Wantedlyのフロントの歴史 5
シゴトでココロオドル • 一気に全体に導入された • 詳しい人は一人だけ – コードレビューもほとんどできない – あまり良くないコードが堂々としている •
みんな書きたがらない – 学習コストが高い – 勉強する余裕がない – とりあえずjQueryでなんとかすればいいか まずはAngular 1を反省 6
シゴトでココロオドル • 書く人を増やすことに尽力した – 社内勉強会を何回も開催した • みんな興味はあるのでちゃんと聞いてくれた – Reactいいよ、と呟く •
一部から導入した – 独立した機能から導入した – 新機能やリニューアル時に少しずつ増やしていった • デザイナーに認めてもらう – 前回Reactで作ったのが良かったから、次もあのクオリティに したい – React前提でデザインが進められる React導入時に注意したこと 7
シゴトでココロオドル • React書く人増えてる – 自分のチームは全員書く – ほぼ全てのチームで導入されている • 10機能で使用されている •
Component数は約300 その結果 8 よかった!
シゴトでココロオドル シゴトでココロオドル いい話はここらへんにしておいて 9
シゴトでココロオドル • React入れるには、他に色々判断しないといけない – 言語は? – どうやってビルドする? – Flux? –
Styleは? – ディレクトリ構成は? – テストは? • 導入当時の選択を振り返って、反省したい React周辺の技術スタック 10
シゴトでココロオドル • Tool – webpack, Babel, ESLint • Library –
Redux, Redux-thunk, Immutable.js – CSSModules, react-css-modules • Other – flux, E2E test 今の主な技術stack 11
シゴトでココロオドル Tools 12
シゴトでココロオドル • Railsからは切り離し、webpackを使っている – webpack-dev-server すごく便利 • 完全なSPAではない • 独立した機能から使い出して、独立したアプリケーション
がいっぱいできた – Entryファイルが機能ごとに分かれている • いざ全体にReactを入れていこうと思ったら、結構困った (困っている) webpack 13
シゴトでココロオドル webpack 14 • 各機能が独立しているので、一 緒に読み込めない • リンク一つで遷移できるはずな のに、ページのフルリロードが必 要
manage_posts.js analytics.js tickets.js messages.js
シゴトでココロオドル • こういうファイルが何個もある – それぞれがstoreを作って、routingしてる • まとめるのはかなり大変 webpack 15 const
store = configureStore(); const history = syncHistoryWithStore(browserHistory, store); ReactDOM.render( <Provider store={store}> <Router history={history}> <Route path='/enterprise/analytics' component={AnalyticsContainer} > <IndexRoute component={DashboardContainer} /> <Route path='company' component={CompanyContainer} /> </Route> </Router> </Provider>, document.querySelector('[react-component=EnterpriseAnalyticsContainer]'), );
シゴトでココロオドル • 反省: アプリケーションは一つで、lazy loadで必要なも のだけ呼ぶようにする • webpackのdynamic importでできる –
ComponentやActionだけじゃなく、reducerもreplaceで きる • Storeやroutingの設定は一つになるように • 全体は一つのアプリケーションで、必要なページで追加の コードが読まれるように webpack 16
シゴトでココロオドル • もともと入れてなかった – Ruby側で使っていなかったから • すごいペースでコードが汚くなっていく – 使ってないのにimport –
中途半端なpropTypes – `==` vs `===` – 人間の目ではレビューしきれない • 途中から導入することに • 詳しくはこちらに – 全力で大きくなるReactのコードをスタイルガイドに沿って見直したら、大変勉強に なりました | Wantedly Engineer Blog ESLint 17
シゴトでココロオドル • 反省: 初めから入れて、徹底しよう • JSのコードは汚くなるもの • エディタでチェックするようにメンバーで共通する • レビューでは気づけないので、CIに入れてもいいかも
• 厳しめに入れて、後から緩くすればいい ESLint 18
シゴトでココロオドル Library 19
シゴトでココロオドル • Immutable便利 – Immutable.Recordでビジネスロジックを持ったオブジェ クトを作れる – OrderedSetなどのデータ構造もよく使う • どこはImmutableで、どこはPlainなのか
– ReducerごとのstateはPlain – EntityをImmutableでつくる – が、徹底して統一するのは難しい Immutable.js 20
シゴトでココロオドル • このオブジェクトは、Immutable? • この配列はArray or Immutable.List ? • propTypesも適当になってくる
– anyがいっぱい • どちらかに統一するというよりは、型が分か れば解決できる問題 – TypeScriptとかなら解決できる Immutable.js 21
シゴトでココロオドル • 状態管理を行うcomponent – 主にReduxとconnectするcomponent • どこからContainerで、どこからComponentにするか – ページ単位? –
Routing単位? – 実はどこでもいい Container(Redux) 22
シゴトでココロオドル • Containerは一番外側のcomponent、みたいに思って いたおかげで、propsの受け渡しが多すぎるひどいコード が増えた • すごく雑なpropTypesや、全部受け取るconnectの出 来上がり Container 23
export default connect( state => ({ analytics: state.analytics, }), dispatch => bindActionCreators({ ...actions }), )(AnalyticsContainer);
シゴトでココロオドル • もっと細かくContainerを分けるべき – 必要ないstateも受けていると、パフォーマンスが 下がる – 受け渡すだけのprosは、可読性も下がるし、書く のもかなり面倒さい •
ディレクトリ構成も一因に – Componentから遠いので、行き来するが面倒 – `import from ‘../../../containers/’;` Container 24
シゴトでココロオドル Language 25
シゴトでココロオドル • ES2015をbabelでトランスパイルしている • Stage-3まで使える – Candidateなので、大きく変わる可能性は小さい • それ以下は要相談 –
`static propTypes =` などは使っている – simpleで変わる心配少ない & 変わっても簡単に直せ る & 可読性がかなり上がる – TypeScriptでもかけるし。。 ES2015 26
シゴトでココロオドル • 型は必要だった? – Railsを書いている人が大部分なので、ハードル が高いと思った • CoffeeScriptからの差が大きい – 今はgolangとか書く人も増えてるし、型の良さも
共通認識である(と思う) – TypeScriptのIntelliSenseがいい ES2015 27
シゴトでココロオドル • 反省: TypeScriptにしても良かった – propTypesも標準じゃなくなるし – Googleでも標準言語になってるし – VS
Codeで生産性高いし • 途中からTypeScriptにするのは骨が折れ そうだから、初めからTSにできるならした方 がいい • Flowでも可 ES2015 28
シゴトでココロオドル Test 29
シゴトでココロオドル • 現:JSの単体テストはなく、Railsも含めたE2Eテストで担 保している • Wantedlyのwebエンジニアは、フロントもサーバーも一 人で書く場合が多い – バーっと動くものをつくって、重要なところをE2Eで担保 していくスタイルがあっていた
• Angular時代も単体テストを書く環境はあったが、ほとん ど書かれることはなかった テスト 30
シゴトでココロオドル • 反省: テストはかけた方がいい • 全てE2Eテストを書くのは大変 • 各Component書く必要はなさそう • ActionCreatorや、ビジネスロジックはテス
トが書かれるべき <- 当たり前 • 環境整えるのが大変なので、誰か助けてくだ さい テスト 31
シゴトでココロオドル Directory Structure 32
シゴトでココロオドル • react/ – components/ • {fooapp, barapp}/ – containers/
• {fooapp, barapp} – reducers/ • {fooapp, barapp} – actions/ • {fooapp, barapp} – lib/immutable/ ディレクトリ構成 33 • 外側は役割ごとに分けられて いる • その中は、機能ごとに同じよう に分けている • 実際はもうちょっと汚い • 初めはflatだった • 一つの機能が離れたところに
シゴトでココロオドル • StateとUIを分けるべき – アプリケーションの状態とUIのReactとは切り離す – ComponentsとContainerはディレクトリで分けなく ても良さそう • 関心ごとにまとめるべき
– 一つの機能に関するコードを近くに集めることで、 データの流れが追いやすくなる • 参考 – Automattic/wp-calypso ディレクトリ構成 34
シゴトでココロオドル • components/ – {fooapp, barapp}/ • Baz.jsx • BazContainer.js
• state/ – {fooapp, barapp}/ • action.js • reducer.js • selector.js • models/ ディレクトリ構成[理想] 35
シゴトでココロオドル Others 36
シゴトでココロオドル • CSSModulesを使っていた – CSSが分かれていて、デザイナーでも触りやすい – Rails側でscssを使っているので、変数の共有な どのために統一した • react-css-modules
– className={style.tabel} – styleName=’table’ – 書く量が減って、いいかなと思った CSS 37
シゴトでココロオドル • react-css-modulesのパフォーマンス – 実行時の解決なので、コストがかかる • babel-plugin-react-css-modules – BabelのCompile時に解決してくれるのでパフォー マンスがいい
– 何が起きてるかわかりにくいbabelのpluginは入れ たくない • 学習コストが上がる • なんでもできちゃう CSS 38
シゴトでココロオドル • シンプルにCSSModulesだけで良かった • className={s.table}って書くだけで、大し て面倒ではない – 直感的に理解できる – undefinedチェックとか実装時はうざいだけ
<= 設 定の問題 – camelCaseのスタイルでもいいじゃん CSS 39
シゴトでココロオドル • State treeからデータを取ってくる関数 – 離れた場所のデータを組みわせて使いたい場面 とかに便利 – redux/reselect を使うとメモ化なども行なってくれ、
パフォーマンスにも優しい • 初めは、render内で毎回計算したり、state に保存したりしていた Selector 40
シゴトでココロオドル • state treeの構造をどうするべきか – APIのデータをそのままstateに入れると、nestが 深くなる – 深いデータが更新されると、上側も全て更新され る
– パフォーマンス的にもよろしくない – データの一貫性を保つのが難しい • Reducerのコードが複雑になる Normalize 41
シゴトでココロオドル • 各entityごとにnestを均してから保存する – IDをkey, entityをvalueにしたMapに保存 – 元あった場所にはIDを入れておく – propsはIDを渡して、connectでentityを取ってくる
• 利点 – 関係ないデータが変更されても、updateが少なく なる – Reducerの処理がシンプルになる • IDからデータを探して更新するだけ Normalize 42
シゴトでココロオドル • Reduxのmiddleware – Actionのdispatchに割り込んで、色々できる • 非同期処理を扱うために、redux-thunkだ け入れた – Simpleでとにかく学習コストが低い
• Loggingなどの副作用や、共有化された APIコールなどで、適宜作っている • こういうところに単体テストがないの良くない middleware 43
シゴトでココロオドル まとめ 44
シゴトでココロオドル • React導入一年経って、うまくいっていると胸 を張って言える • チームの状況を見てスタックを選択しよう – Wantedlyは一人がサーバーとフロントを両方書く 体制 •
大きな失敗はないけど、もっとよくできたと反 省は絶えない • これから導入する人の参考になれば嬉しい まとめ 45
シゴトでココロオドル We are hiring! 46 https://www.wantedly.com/projects/59809