1
/
5

ログラスのReactの技術選定について🐳

はじめに

こんにちはログラスのフロントエンドエンジニアの @Yuiiitoto です。
「次世代型経営管理クラウド」のSaaSを開発しています。

今回Reactを使って開発しているログラスのフロントエンドがどういう技術を使っているのか、なぜそれを選んだかについて解説していきます。

Reactはライブラリの数が豊富な反面で群雄割拠している領域が多く、技術選定がとても大変です。
同じ悩みを抱えるフロントエンドエンジニアの方に少しでも力になれればと思って記事にしました。


ログラスのフロントエンド

似たようなサービスの場合に特に参考にできる場合が多いと思うので、記事の前提としているサービスについて少し説明します。

ログラスはいわゆるtoBのSaaSの業務システムみたいな立ち位置です。
ほぼ全てのページに認証が入り、画面の中の要素はtoCのサイトより多めです。
Next.jsで構成されていて、SSGやSSRなどは使わずにデータはクライアントからフェッチしています。


※ログラスは事業の予実を管理するサービスです。

解説する領域

今回、技術選定する領域は以下の3つです。

  1. 状態管理
  2. スタイリング
  3. フォーム

状態管理

状態管理はSWRとContextを使った状態管理をしています。
APIからの値はSWRで管理していて、それ以外の値はContextを使って管理しています。

他に考えた選択肢では以下が挙げられます。

  • Redux + Redux Toolkit + redux-thunk(or saga)
  • Redux + Redux Toolkit(非同期はTooklit内の機能のAsync Thunk)
  • Redux + CustomHook

なぜSWR + Contextなのか

アプリ内で状態管理したいものが大抵はAPIのデータ + SWRはそれに特化したライブラリだからです。
大抵のものがSWRで管理しているので、それ以外のものをReduxで管理するのは学習コストとしても見合わないとしてContextを使うという判断をしました。

また、Reduxを使う場合はアプリ内で中央集権的に管理せざるをえなくなるので、マイクロフロントエンドやコンポーネントライブラリの切り出しが将来的に難しくなると判断しました。
たとえばモーダル(ポップアップ)などの開閉状態をアプリ全体で保持したい場合、Reduxを使うと他のストアの情報と依存してしまいますが、Contextの場合は依存を最小限に抑えることが可能です。

SWRのメンテナンス性ですが、Vercel製で公式ドキュメント内でも使用が推奨されていることもあり、問題ないと判断しています(まだv0.xだけど)。

The team behind Next.js has created a React hook for data fetching called SWR. We highly recommend it if you’re fetching data on the client side. It handles caching, revalidation, focus tracking, refetching on interval, and more. And you can use it like so:


Basic Features: Data Fetching | Next.js
This document is for Next.js versions 9.3 and up. If you're using older versions of Next.js, refer to our previous documentation. In the Pages documentation, we've explained that Next.js has two forms of pre-rendering: Static Generation and Server-side Re
https://nextjs.org/docs/basic-features/data-fetching#swr


SWRの紹介として、以下の記事なども参考になります。

SWR: React Hooks for Data Fetching
"SWR" という名前は、 HTTP RFC 5861 で提唱された HTTP キャッシュ無効化戦略である stale-while-revalidate に由来しています。 SWR は、まずキャッシュからデータを返し(stale)、次にフェッチリクエストを送り(revalidate)、最後に最新のデータを持ってくるという戦略です。 この例では、 useSWR フックは key 文字列と fetcher 関数を受け取ります。 key はデータの一意な識別子(通常は API の URL)で、 fetcher
https://swr.vercel.app/ja


そうです。わたしがReactをシンプルにするSWRです。
SWR について色々と学んだので、その知見をここで共有したいと思います💪 ※ 基本的に以下の公式サイトの情報を参考にしています📖 そのため、この記事で出すサンプルコードなどは主に上記の公式サイトから引用させて貰っています。予めご了承ください🙏 SWRは、Next.jsを作っている Vercel社が開発しているデータフェッチのための React Hooksライブラリです。"SWR"と言う名前は、 stale-while-revalidateの頭文字をとって名付けられています。そのため、SWRは stale-
https://zenn.dev/uttk/articles/b3bcbedbc1fd00


スタイリング

非常に悩ましい領域ですね。ここだけで一つの記事になりえます。
最終的にログラスが選んだのはemotionでした。

他に考えた選択肢は以下の4つです。

  • CSS Modules
  • Styled Components
  • Tailwind CSS
  • linaria

CSS ModulesはNext.js推奨??

まず物議をかもしているのがこちらのIssue。

We should update the page to be clear about the advantages of CSS Modules over css-in-js, mainly being that you don't need JS to add the CSS as CSS Modules are concatenated into many minified and code-split .css files. Ideally users should end up thinking that CSS Modules are the preferred solution, but any CSS-in-JS library is also an option.

どうやら最適化の観点からNext.jsは今後CSS Modulesを推奨していくような流れを感じ取ることができます。
しかしまだOPEN状態なIssueなので確定というわけではないですが、CSS Modules→CSS-in-JSという流れだったものを見事に逆行させるIssueです。

国内での詳しい考察は以下の議論でも確認できます。


Next.js が CSS Modules を推奨する真相に迫りたい
Next.js 9.2 から CSS Modules がビルトインサポート対象になった。 CSS最適化に関して、組み込みサポートのレールから逸れると、ページ単位で最適化された静的CSSの生成不全に陥る。少しでもパフォーマンスの良い Next.js App を構築したいのなら、CSS Modules 一択というのが現状で、CSS in JS に慣れ親しんだ身からすると正直辛い現実だ。 CSS in JS よりも CSS Modules の方が、ロードタイム・ランタイムともに、パフォーマンス面で有利なことは知
https://zenn.dev/takepepe/scraps/6668e9fe402666


この一連の流れを見たときに、それでもなおログラスではCSS-Modulesを採用しませんでした。

CSS-Modulesの考えられるデメリットは以下のようなものがあげられます。

  • ファイル数が増える
  • タイプセーフではなく、存在しないクラス名も当てられる。検知がエディター依存になる

また最適化の観点からもログラスのフロントエンドはほぼすべてのページで認証がかかっておりSSG、SSRは採用していなく、またそこまでスピードを求められるサービスではないため観点として除外しました。

王道のStyled-Componentsか

おそらく一番使用者が多いのはStyled-Componentsでしょう。
しかしこれは以下の理由で採用しませんでした。

  • Styled componentsを使うかcss propsを使うかで迷う
  • Styled componentsなのか普通のコンポーネントなのか一見してわかりにくい
  • Angular,Vueの人の学習コストが少し高い

特に3つ目のAngular Vueの人でも学習コストが高いというデメリットはログラスでは重要な観点の一つです。

最終的なEmotionのスタイル

最終的には以下のような書き方で落ち着きました。

const Todos = () => (
  <ul css=styles.list>
    <li css=styles.listItem>
      aaa
    </li>
    <li css=styles.listItem>
      bbb
    </li>
    <li css=styles.listItem>
      ccc
    </li>

  </ul>
);

const styles = {
  list: css`
    display: flex;
  `,
  listItem: css`
    margin-left: 8px;

    &:first-of-type {
      margin-left: 0;
    }
  `,
}

この書き方であれば生のCSSに近い感覚で書けるのでAngularやVueの方でも不自由なく書けそうだと判断しました。

フォーム

お次はフォームです。フォームは以下の3つの選択肢から考えました。

  • React Hook Form
  • React Final Form
  • Formik

最終的に選んだのは React Hook Formです
しかしこれは正直React Hook Form と React Final Formのどちらかであれば好みの問題だと思います。
Formikは明確にパフォーマンスの観点でデメリットがあるので使用はおすすめしません。

議論の参考としては Blitz作者のフォームの比較記事が参考になります。
日本語の要約記事はこちらです。


Blitz.jsの議論から学ぶ,formik vs react-final-form vs react-hook-form - Qiita
BlitzがどのFormライブラリをデフォルトにするかの議論が参考になったので要約しました。 の3択で,結論としては, React Final Formを推奨とする 形に落ち着きました。 Blitz.jsの作者であるBrandon(@flybayer)さんがコメントしています。要約するとこんな感じ。 Formik 以前使ってたけど,パフォーマンスめっちゃ悪いって気づいたから,Formikは無しで。 React-final-form 最近ずっと使ってるけどいい感じ。 React-hook-form ほとんど
https://qiita.com/marin_a__/items/eee408c5e99d5b53416e


Formik
以前使ってたけど,パフォーマンスめっちゃ悪いって気づいたから,Formikは無しで。
React-final-form
最近ずっと使ってるけどいい感じ。
React-hook-form
ほとんど使ったことない。

記事ではこう要約されています。

React Hook Formは初めからReact Hookをもとに設計されているので、 フォームのロジックなどをカスタムフックに切り出すことが容易にできます。
useControllerなどを使えばコンポーネントの分割も簡単に行えるので個人的には一番オススメできるライブラリです。

To Be Continued

今回は全体の技術選定ということで深くは解説はしませんでした。
もし今回触れた3領域で詳しい話が聞きたい場合はぜひご連絡ください。

また今回触れてなかった領域で以下が挙げられます。

  • テスト
  • スタイルガイド
  • ディレクトリ構造

これらもリクエストがあれば順次まとめていくのでもし興味があればご連絡くださいー!

We're hiring!

ログラスはこの記事を見ているあなたのような好奇心旺盛なエンジニアを求めています。
興味があればぜひご応募ください!

株式会社ログラスでは一緒に働く仲間を募集しています
3 いいね!
3 いいね!
同じタグの記事
今週のランキング
株式会社ログラスからお誘い
この話題に共感したら、メンバーと話してみませんか?