trancore / todo

Todo Application
0 stars 0 forks source link

Next.js開発環境構築と技術選定 #18

Closed trancore closed 8 months ago

trancore commented 9 months ago

タスク概要

参考になりそうな資料

作業

完了条件

trancore commented 9 months ago

CSSについて

Next.jsでは、テンプレートがJS内で記載される(JSX)ことから、CSS-in-JSの方が親和性が高い気がする。 とすると、CSS modulesかStyled Componentがよく使われているものになるため、この2つから選定したい。

CSS modules:

Styled Component:

以上を鑑みつつ、まだstyled componentを触ったことがないので、Styled Componentで実装する。

trancore commented 9 months ago

状態管理について

TODOアプリでは、あまり複雑な状態管理を行わない or 不要な気もするが、一旦調べてみる。

Redux

Context & Reducer & Hooks

Recoil

jotai

Zustand

調べてみたが、Recoil, jotai, zustandのライブラリは学習コストが低く、簡単に扱える印象を受けた。 また、いわゆるAtomパターンで、どこからでも手軽に状態の取得・更新ができる利点がある。しかし、あまり深く考えずに状態の更新をしてしまうと、予期せぬ状態の更新が起こってしまうのではないだろうか。

一方古くからあるReduxは、学習コストは高く理解するにはそれなりに大変。 しかし、堅牢な状態管理フローは一度理解してしまえば扱いやすいのかも。

以上を考慮して、Reduxフローを学び直したい、手軽すぎると学習に向かなさそう、RTK Queryを使いたいので、Reduxで状態管理を行う。

trancore commented 9 months ago

fetch

Next.jsでは、Server側とClient側でfetchの方法が異なる。 Server側では、getServerSideProps, React Server Components(RSC)がある。 Client側では、SWR, TanStack Query, RTK Query, useEffectがある。 さらに、fetcherには、Axios, fetch, graphQLがある。

Server

getServerSideProps

Pages RouterでSSR時に処理を行うための関数。 Pages Routerでは、pre-renderingによってHTMLが生成される。この時、ページのリクエスト毎にHTMLを生成するのがSSRとなる(一方で、build時にHTMLを生成するのはSG)。 だが、このgetServerSidePropsというのはNext.js独自の概念で、React.jsでは存在しない。

ちょっと話題が逸れるが

最新の情報を取得し、HTML生成とともにデータが揃っていれば、ページ解析時により良いページ情報を提供できることになり、SEOにも良い影響がでる。もちろんこれはSG時も同じ(しかしSGの場合、buildを頻繁に行わないとデータの鮮度が落ちる)。

React Server Components

React.jsでの概念で、Server側でレンダリングされるコンポーネントとClient側でレンダリングされるコンポーネントで分けることができるようになった。 そして、SSRの場合は、Client側のコンポーネントでもSSRでレンダリングすることができる(ちなみにSSR無しでは、Server側のコンポーネントだけHTMLにgenerateされる)。 このRSCを使うことで、パフォーマンスの改善とバンドルサイズの軽減をすることができる。

Client

useEffect

コンポーネントを外部システムと同期させるためのReact Hooks。 コンポーネントのトップレベルかカスタムフック内でしか呼び出せない。 画面描画後に実行されるため、ちらつきが起こる場合は、useLayoutEffectを使う。 さらに、state更新の際にも再描画を行なってしまうため、この場合もuseLayoutEffectに置き換える必要がある。

SWR

SWRはキャッシュ機構を持ちつつデータフェッチを行うことができる。 SSRやISR, SSGにも対応している。 RSCを使う場合は、Client側コンポーネントでのみ使うことができる

RTK Query

RTK Queryも、データフェッチとキャッシュに対して強力なツールとなる。シンプルにデータの読み込みするようにデザインされており、手書きでデータの取得やキャッシュを書く必要がなくなる。 Redux toolkit packageに含まれるアドオンである。 Reduxを使っているなら、これを使うのが良いかも。

TanStack Query

元はReact Query。 データフェッチによる取得や更新、キャッシュ機能を持つ。 バンドルサイズも小さく、やれることも他に比べて多そう。 Comparison | React Query vs SWR vs Apollo vs RTK Query vs React Router

上記調べたが、 Server側は、最近導入されたRSCを触ってみたいため、RSCを導入することとする。 Server側は、Styled-componentがApp Roterに対応していないため、Pages Routerでの取得に変更する。(2024/02/18) また、Client側は、状態管理ツールとしてReduxを使うため、RTK Queryを使う。

trancore commented 9 months ago

mock

すでにAPIサーバーの開発は完了しているため導入するメリットが無いが、やってみたいので、実装することとする。

Route Handler

App Routerの場合では、Route Handlerを使うことで、データフェッチを扱うことができる。 これで持ってモックデータを定義し、fetchからパスを指定すればモックデータとして値を取得できそう。 ライブラリなどを入れる必要がなく、フレームワークが提供する機能なので安心。 サーバーをいちいち立てる必要も無い。

json-server

npm packagesを追加すればすぐにリクエストできるmockサーバー。 DB(keyvalue型のlowDB)の定義もできるので、POST, PUT, DELETEなどもリクエストすることができる。 Swaggerを取り込むことはできないので、APIを一つ一つ手動で定義する必要がある。 REST API, GraphQL APIにも対応できる。 リクエストそのものをインターセプトしているので、環境変数ひとつで本番環境、開発環境へのアクセスを切り替えることができる。

msw

環境やフレームワークに影響されないJSのAPIモックライブラリ。 Devtoolsでモックされたレスポンスを見ることができるし、Service Workerに書く必要がない。さらにテストでも使えるみたい。 Service Worker(ブラウザ)、Node.js(サーバー)でも動くので、SSR/CSRにも対応している。ブラウザで動かす場合と、サーバー上で動かす場合とで設定方法が異なるのに注意。 Swaggerを読み込んで、設定無しによしなにやってくれる機能はない。この辺りは自分で実装する必要がある。 (参考:Generate API responses from swagger doc

Jest

msw以前は、Jestを使ったモックサーバーがよく使われていたそう。 Jest - モック関数 - モジュールのモック

そもそも、jestがtesting libraryであるため、テストと組み合わせる場合は良さそう。 しかし、テストのためのモックであり、画面開発としてのモックサーバーとしては使い勝手が悪そうと思った。

Prism

OpenAPIでのAPIモックとテストを行うことができるパッケージ。 そのため、Swaggerを読み込ませれば、すぐにAPIモックとしてリクエストをすることができる。Swaggerがあればお手軽にモックサーバーを建てられる。

上記より、mswかprismになる。 prismはお手軽すぎるがレスポンスを自由に変えるための実装をしてみたい。mswは触ってみたいが、導入から使えるまでに時間がかかりそう、、 悩んだ末、mswで実装することにする。

trancore commented 8 months ago

テスト

Next.js公式によると、テストの段階によって、テスティングライブラリを使い分けることが説明されている。

App Routerの場合

テストも書いていきたいので、単体テストはJest, testing-libraryを使って書いていく。 ちなみに、testing-libraryを入れる理由は、便利なテスティングマッチャーが使えるようになるから。 結合テストはCypressを使っていく。

trancore commented 8 months ago

以上技術を使って実装していく。

trancore commented 8 months ago

忘れていた。。

fetcher

axios

3rd party製のデータfetchライブラリ。 豊富な機能を持ち、エラーハンドリングの実装やレスポンス変換がしやすい。

fetch

ブラウザに組み込まれている。 シンプルにHTTP通信を行うことができる。

graphQL

データを呼び出す側が求めるデータをクエリに含め、柔軟なIFでデータを取得する。 今回のデータfetch方法はRestfulなAPIなため、これを用いることはできない。

上記より、axiosを使うことにする。

trancore commented 8 months ago

さらに忘れていた。。

Form

React Hook Form

Formik

Redux Form

まとめてくれている記事を添付しておく。 Qiita - Reactのフォームライブラリを比較してみる

こちらにまとめてくれているように、React-Hooks-Formを使う。

trancore commented 5 months ago

さらにさらに忘れていた。

言語

built-in

Domain Routing

ドメインルーティングを使って、ドメインごとに言語情報を分ける。

Sub-path Routing

URLのパスに言語情報を含める。

next-intl

next-international

next-i18n-router

paraglide-next

lingui

next-translate

next-i18next

これらパッケージのトレンドは以下のリンク先の通り。 npm trends

調査時の順位は以下の通り。

  1. next-i18next
  2. next-intl
  3. @lingui/core

The i18n routing support is currently meant to complement existing i18n library solutions like react-intl, react-i18next, lingui, rosetta, next-intl, next-translate, next-multilingual, tolgee, paraglide-next and others by streamlining the routes and locale parsing.

公式では、ライブラリありきっぽい。国際化ライブラリを補完するもの、という説明をしている。

なので、built-inだけで実装するのは想定していなさそう。 npm-trendsの順位とNext.jsのドキュメントで紹介されているnext-i18nextを使用したいが、next-i18nextはCommonJSしか対応していないため、next-intl を使う。

参考

trancore commented 3 months ago

さらにさらにさらに忘れていた

SEO

https://nextjs.org/docs/pages/building-your-application/optimizing

Next.jsでは、どのようなSEO対策を行うことができるのか。