プロトタイピングツールPrott
今、ゼロからのリニューアル計画が動いています
先月から始まった0→1のプロジェクトにおいて
意見の一つとして参考になればと思い
どんな考えでどんな技術を選定したかをご紹介します。
採用したフレームワークやツール
- React
- Redux
- Flow
- styled-components
- AVA
- yarn
技術選定基準
- Web標準に即している、もしくは乖離しすぎていない
- 別のツールを使うことになったときに乗り換えやすい
- ある程度以上に枯れていて、情報量が多い
- エコシステムが発達している
- 解決する対象以上の難しさを持ち込まない
このへんを意識しています。
守れているかはケースバイケースというか、メリットが上回れば背いてしまうこともありますが・・・
React
- 最初はAngularを検討
- 使い心地は好きだけどまだ枯れていなくて情報が少ないのと、当時(2017年1月頃)はAPIの変更が多くて調べる時間が長かったので、大きめのチーム開発に採用して自分が舵取りするのはなかなか難しいかもと判断
- Reactは枯れているしライブラリも色々あり破壊的変更も少なそう。メジャー=エンジニア人口も多く採用面でも有利かと判断
Redux
- プロジェクトに人が増えたり自分の手が細部まで回らなくなったとき、自分の設計がそれらを統制するだけの強い一貫性を持てるだろうか?ドキュメントは充実させられるだろうか?啓蒙はできるだろうか?
- 上記コストを既に払ってくれていて、十分にテストやメンテナンスもされていて、情報やエコシステムも育ってきている既存のレールに乗っかったほうが安牌なのでは
- "レールに乗ったほうが設計思想を共有するコストが減る"
Redux - 設計面
- ReduxでのMiddleware不要論 - Qiita
- ReactにもReduxにも依存しないかたちでピュアにドメインロジックを書けていてよい
- 追記: actionのchainが必要になってきたため、現在は薄いredux-thunkを導入している
- 一番上の階層だけでなく、適切な単位でContainer Componentを挟む
- ルーティング後の最上層でその画面のすべてのリソースを取ってきてバケツリレーするより、あるコンポーネントが使うデータはそのコンポーネントが取ってくる形のほうがいいと思う(粒度は考える)
Redux - 使ってみて
- 関数型的なパラダイムの方面へ矯正される感覚がある
- 無意識にOOP的な考え方をしてしまうところがあったので
- 冗長に感じる
- ひとつのことをするのに3つ4つのパーツを増やさなければならない
- 思想を理解せずにレール欲しさで持ち込んでしまった感
- 解決する対象以上の難しさを持ち込んでしまっている…?
- でもこれぐらい層があったほうが変更にも強く切り分けも楽そう
Redux (追記)
- 最初Middlewareなしで始めて、あとから必要になって入れたので、Middlewareの必要性も理解できた。
- 「このentityをdeleteするときはぶら下がるこっちのentityもdeleteしたい」とか、stateを参照しながら複数のactionをまとめて扱いたいニーズがあった
- あとから入るメンバーの学習コストが心配だったが、store(state + reducer)とreact-reduxのconnectが理解できればわりといけそうな感じ。
- この資料がとても役に立ちました。感謝。
既存のリニューアルリポジトリ上でやる前提で、こんな感じで簡単にアレンジしてみた
Flow
- 既存の負債を踏まえても型は欲しい。FlowとTypeScriptで悩んだ
- 「言語をTypeScriptへスイッチする」よりも「JSに型チェックの機能を付け加える」アプローチのほうがライトでいいかもと思った
- Flowの型推論が賢いという情報をよく見た
- babelで変換できるしReactとの相性がよさそう
はまりどころ
- flow-typedに型情報があるライブラリが少ない
- node_modules以下を読むと死に、ignoreするとimportが解決できなくて死ぬ
- 今はnode_modulesをignoreして、flow-typedになくてエラーになるライブラリはdecls以下に自分で定義(ほぼany…)を書いている
- 仕様確定前のproposalsがだいぶ使えない
- decoratorが使えない(無視はできるが中を見てくれない)の結構痛い
- decorator使わない方針にした。まあ仕様確定前なのでこれが正しいといえば正しい気はする。。
はまりどころ
// @flow
書き忘れる
- styleファイルでエラーが出るので--allができない
- 漏れ対策としてlintとかcheckの仕組みを入れたい
- WebStormでリアルタイム実行すると重すぎて文字が打てない
- DockerやCI上で実行するときうまくいかないケースが多かった
型いれて助かってるけど、このへん省みるとTypeScriptだったらどうなってたかなー…と思う。ただTypeScriptだとeslintが使えないのが辛い。。。
styled-components - 設計面
React+Reduxでのコンポーネントの粒度はそこまで気にせず、デザインをコーディングする上で必要な1要素ごとにコンポーネント化する。
ビュー側でそれらを必要に応じてimportし、使う形。
既存のコンポーネントにスタイルを定義する形ではないので、似たコンポーネントどうする問題が解決される。(同じデザインの箇所だけ同じstyled-componentsを使えばいい)
styled-components - 設計面
AuthBox, Title, Buttonがstyle用のコンポーネント
<AuthBox>
<Title>Sign in</Title>
<SigninForm onSubmit="this.signin"/>
</AuthBox>
<AuthBox>
<Title>Sign up</Title>
<SignupForm onSubmit="this.signup"/>
</AuthBox>
メリット
- コンポーネントごとにスコープを切れる
- JSとCSSで値を共有できる
- そのスタイルがどこで利用されているのか把握できる
- あるコンポーネントにスタイルの定義を追加するのではなく、スタイルのあたった空コンポーネントそのものを作るので使い回しがしやすい(CSSクラスをあてる感じ)
- スタイルのsyntaxが標準のCSSから(わりと)乖離しない
- JSが特定のツールに依存せずvalidである
- stylelintを使える
- propsを受け取れるので値をサイズに適用するとかめっちゃ楽
デメリット
- 他のメンバーの意見を聞くと、やはりCSSはクラスベースのほうが馴染みがありそう
- DevToolsで要素を探しづらい
- CSSCombでの並び替えができない
- パフォーマンス面まだ問題ないけど今後どうか要チェック
理想
- コンポーネントベースだとWeb Componentsなんかでも使える設計になるかなと思ったけど、やっぱりクラスベースのほうが馴染みやすいし便利な面も多そう
- ただビルドツールに依存したCSSのimportは極力したくないので、CSS in JSでvalidに解決したい。
技術選定してみて思ったこと
- 迷ったらまず小さいプロジェクトで使って試してみるの大事
- 採用基準は人(チーム)や状況による。自分は何を基準にして何を優先したいのか言語化しておくとよい
- 私は情報の多さやエコシステムの大きさを重視する派
- 自分のやりやすさよりみんなのやりやすさを優先したい
- 解決される問題よりもコストが上回っていると感じたらすぐに見直したほうがいい
- 導入前に考えすぎるよりも、動かしてみてだめならぱっとやめるほうが効率いい(苦手。。)
- 最初から100点の判断なんてできないから、フットワーク軽くいこうぜ!