janjan's blog

フロントエンド開発における設計とか、重要にしていること

Published: 2020/7/29

フロントエンドを触り始めてもうすぐ 2 年くらいになるので、自分が思うフロントエンド開発についてまとめる。これは今できていること、できていないこと、これからやりたいこと、妄想も含まれる

バックグラウンド

フロント経験 1 年 10 ヶ月くらい?(2020/07/29 現在)

技術スタック

  • React / Redux
  • TypeScript
  • Jest / testing-library-xxx
  • storybook
  • webpack

前提

プロダクションレベルで書いたことあるのは React / TypeScript がメインなので主張の軸はこの辺になる

設計

自分が大事にしているのはこの辺り

  • ビューとロジックを分ける

    • 同一のコンポーネントに分けるとファットになり、可読性、メンテナンス性、再利用生など運用していて辛いことが多いので避けたい
    • React であれば、React Hooksの登場でコンポーネントから切り離すことができるようになったので積極的に使っていきたい - おおよそ、useXXXX というロジックが出てくるのだが、その中にどれくらいのロジックを含めるか・分割するかは悩むところではある(なんかいい例があれば書く)。
    • 画面と密接に関係するアニメーションや IntersectionObserver などは、画面個別になるイメージなので同じコンポーネントに書く感じ(この辺はまだ悩んでいる)
  • テストを諦めない

    • フロントのテストは割と敬遠されがちです(勝手なイメージです)が、最低限ロジック部分のテストは書く。ここで最低限と書いているのは、新規プロダクトなら全部書く、というのが個人では must だと思っているが既存のプロジェクトかつ今テストがまともに書かれていない場合はロジックからという意味である。
    • 上でも書いているが、ロジック部分のテスト useXXXX はという形であれば昔の React コンポーネントをテストするよりは書きやすいと思う。このへんは Jest/testing-library ファミリーのライブラリを使うことをお勧めする(Kent C. Dodds 信者です)
    • インテグレーションテストや e2e もあると尚良い
    • e2e は Cypress を軸に testing-library-cyress を利用すればテストは書きやすいと思う
    • 画面単位のコンポーネントはスナップショットテストを行う
  • プロダクト固有のものはなるべく一つのものにまとめる

    • 特にカラー、テーマ、アイコンなどプロダクト固有であるものは、一つのディレクトリ にまとめ、カラーなど css で使うものやルーティングで使う URL は定数にする。
    • これは個人的な失敗で、うまく統一できなかったからカラーの変更や影響範囲の特定に時間がかかることがあったためである。
  • API 通信のレスポンス型は自動生成に頼る

    • 今のプロジェクトでは OpenApi with Axios でやっているのだが、これがないと API 部分の変更が大変であり、バックエンドとの型合わせ不整合によるしょうもないバグが発生する要因となる。
    • また TypeScript を使うことでコンパイル時エラーとなるので、影響範囲も特定しやすい
  • Global State(以降、store)はなるべく Pure なレスポンスの状態で保つ

    • API レスポンスを store に入れてそれを画面に表示するというユースケースは多いと思うが、表示にそのままの値を利用するということは少ないと思う。このとき、API レスポンスを表示用に変換した値を store に入れると他で使う側からしたらノイズになる。場合によっては無駄に変換してなくてよい、みたな場合もあるかもしれないが、それはたまたまであり変換処理として別に切り出した方が良い。
    • store からコンポーネントに注入する値の変換は、useSelector や reselect を使う
    • API -> reducer -> store の reducer 部分でごにょごにょしない。ということであり、上記を使えば変換部分だけのテストで動作を担保できるためそれで良いのではと思っている。
  • なんでもかんでも store に登録しない

    • store に入れてしまえばどこでも使えるけど、どこからでも参照できるというのは逆にリスクであると思っている。また rerender のコストも考慮する必要がある
    • 画面や機能単位で部分的な store(useContext,useReducer)で実現した方が参照箇所が限定され、何か影響があったときも限定的になる

設定

React に限定だが、設定周りで思っていること

  • Webpack の構成は create-react-app ではなく、オリジナルで小さなもので保つ

    • 最初は create-react-app に乗っかれば万事 OK だと思っていたが、実はそんなに Webpack で設定するものは多くないので、プロジェクトの大きさや用途に合わせて必要なものを追加していく方が良い
    • プロダクトで使う環境変数やその他設定は別ファイルに切り出し、webpack にインジェクトする方が管理が楽
  • ESLint を採用する(みんな使っていそうだし、好きなルールを当てればよい)

    • eslint-plugin-react-hooksは必ず入れ、git hook とかでチェックするようにする。事前に事故を減らせるし、deps をトリッキーに扱うとデグレの元になる

最後に

といろいろ書いていたが、コードないといってることわからんみたいなところがあるのでそのうち書く。この中に入れていないことで、ディレクトリ 構成の話、CSS in JS なのか sass なのかの話はどちらでもよいのであんまり気にしていない。今は styled-component が書きやすいのでそれで良いと思っている。ディレクトリ 構成は 書いていて思ったのが、結局は責務分離が一番自分が大事にしているとわかった。それは、コンポーネントだけでなく、設定もそうだ。責務が複数あるものはファットになりがちだし、割れ窓みたいな感じでどんどん加速していく。そのためにも、縛るという意味で責務は分離すべきという風に思うようになった。

あとは、reducer の扱い方や action の扱い方は人それぞれだと思うので、いい意見があれば自分も直ぐにこの辺りの考えは変わると思う。今のところ、っていうところと自分の経験値上こんな感じだろうと思っている。

自分はこう思っているとか、いろいろ意見があれば Issues とかで議論できればと思う。