Next.js
create-next-appは使っていけばよい。
Nuxt.jsとNext.jsでrouterかlinkがどうとか言っていたな。
App Routerとは?
Next.js13から登場した新しいルーティング機能、従来のPage Routerとは実装方法が異なります。現在最新版を導入するのであればApp Routerを導入することが推奨されています。(従来のPage Routerを導入することも可能)
ただ、まだ出たてなのでライブラリの対応が追い付いてなかったりすることもありリスクがあるためあえて採用しないという選択肢はある。
使い分け
表示系→サーバーコンポーネント
操作系→クライアントコンポーネント
の使い分けが推奨されているようです。サーバーコンポーネントの方が早いので。
また、ページ内で一部コンポーネントだけクライアントコンポーネントにする
・buttonだけクライアントコンポーネントにしてStreaming with Suspenseで先に描画する。もしbutton自体も表示状態などを持つようであれば、サーバーコンポーネント「buttonfetcher」で囲う。
・フォーム部分だけはクライアントコンポーネントにする。(これも「Server Actions」というもので今後サーバーコンポーネント化できる可能性があるとのことですが。)
React
18の機能は基本的にNext.jsに内包されているので意識はあまりしなくてよい。(ただ、useTransactionだったりは使う機会はあるかもしれない。)
Nodeのバージョンの固定化の方法
いろいろあったよね。余裕があれば調べてみるか。
設計思想
atomic Design
atomic Designならpagesとtemplateはデフォルトで保持しているので不要。
なお、似たような機能で共通している内容についてはできるだけ共通化する。(例:baseButtonなど)
API取得部分についてはカスタムフックを使う。(ただ、サーバーコンポーネントではカスタムフックは使えない)
コンポーネントロケーションパターン
atomic Designとは水と油になる。
機能単位でコンポーネントを用意する。Next.jsのApp Routerであれば予約語(errorやpageなど)以外であれば普通のコンポーネントとして扱えるのでこのパターンが使いやすい。(page routerだと厳しい)
features
Tree Design
コンポーネントを木構造にして作る。
設定
- 絶対パスでインポートできるようにする。
例外処理
コンポーネントエラー
Error Boundaryを使う。
その他エラー
try~catchで捕捉する。
プログラミング
- オブジェクト比較はlodash使わないなんかデフォルトでよいやつあったよね。
認証基盤
Auth0?、Firebase?、Cognito?、supabase?それともそれ以外にある?
でも、普通に考えたらリプレイスするシステムであればすでに認証基盤はあるはず。(既存DBなどで)
認可
そういえば実装したことないな。もし各画面でち密な制御が必要な状況であれば何か考えた方が良いかもしれません。
環境
development環境、ステージング環境(VercelだとPreview環境と呼ぶ)
検索エンジンにインデックスさせないようにする。
HTTPヘッダーの設定をする。Next.jsであればnext.config.jsにnoindexを指定すればOK。(vercelならデフォルトで設定されるが、独自ドメインを利用する場合はnext.config.jsで設定しないとダメ。)
関係者以外にアクセスされてはいけないのでサイトにパスワードをかける。
ベーシック認証。Next.js12以降で使えるMiddlewareを使えばできます。
(12以前は、もしVercelでかけたい場合は月15000円程度かかっていたがこの点は改善された。)
本番環境
環境変数管理
direnv?、cross-env?、これはjQueryの奴をそのまま踏襲すればよいはず。
Vercelなら環境変数を管理画面から環境ごとに設定できる。
モック
mock service worker?http-server他に何かあったかな。これは要求次第かなあ。
- ローカルではモックで動かせるようにする。
- ビルド後だけ結合テストができるようにする。
とするとCharlesとかも導入した方が良いって話になるのかな。
HTTPクライアント
request?、axios?、fetch API?それとも他になにかあるか。reduxだったらreduxtoolkitになかったかな。
サーバーコンポーネントに関しては
これはReact18や、Next.js13を使っていくならfetch一択っぽいです。Next.jsで独自の拡張がなされていてキャッシュオプションが使用可能になっていたりします。
ただ、もしgraphQLを使っていてapollo clientなどを使っている場合は容易に使えないと思うのでサーバーコンポーネントは使えないです。(graphQL環境なら無理してApp Routerに移行しなくてもよいかもしれません)
クライアントコンポーネントに関して
APIでフェッチするデータがもしあるのであればキャッシュ機能があるReactQuery or useSWRが良いです。fetchも使えるのですが、Next.jsで拡張されたfetchを活用することはできないためです。
非同期処理
React Query、SWR?、Redux thunk?
ただ、React18やNext.jsなどのサーバーコンポーネントを使う場合は、これらは不要になる。
フォーム
react hook form?それ以外にある?
パフォーマンス
useMemo、useCallback、memoあたりは普通に導入するが、React18のuseTransaction、useDeferredValueなどは普通に使えそう。(ただしuseTransactionは基本は使わないことmemoやcallbackを使っても遅くなるようであれば使用を検討すること)
ローディング
これもjQueryの方にあるか?もし実装するとしたらNext.jsやReact18にそういう機構がある。(suspenseでいける)
もし、Next.jsやReact18のsuspenseでローディングを行った場合react-queryとかのローディングとは競合するか?
TypeScript
readonlyとか使った方が良いのか。
正規化
normalize?やるかどうかも含めて。でもできればやった方が良いんだろうな。
状態管理
アプリデータ
Recoil?Redux?Zustand?
Reacoilってデフォルトでイミュータブルな実装になるのか。
個人情報を含まないサーバーデータ
Next.jsのSSR、SG+ISRなどでやってしまえば良いので特にフロントエンドでの状態管理が不要です。ただ、環境的に静的配信になる場合はReactQueryでキャッシュしても良いです。
個人情報を含むサーバーデータ
ReactQueryが一般的(キャッシュにはすべてのコンポーネントがアクセスできるため)、useSWR。
もしサーバーコンポーネントやSSR、ISRを積極的に使っていくのであれば使う機会は減る。実際にReact Queryの作者もサーバーデータ取得に関してはサーバーコンポーネントによるフェッチに移行するよう推奨し始めているらしいです。(もちろん、サーバーサイドでデータフェッチンぐできないケースもあるのでその場合は今後も使われる)
ただ、個人情報を含みキャッシュなどをしたくないページはクライアントサイドでフェッチするReactQueryなどを使うのが一般的。(ReactQueryはJavaScriptのメモリにキャッシュしてくれるのでWebサーバーやCDNのキャッシュと違って外部漏洩の心配が少ないため)
パッケージ管理
npm?yarn?どちらにするか。
devDependencyに移さないといけない。
linter関連とか、
ビルドツール
Vert?、webpackの代替技術である「Turbopack(ターボパック)」を使う?
turbopackだとi18n関連のオプションが使えないので注意が必要とのこと。
CSS
styled-component?、tailwind?それともほかに何かある?
また、Next.jsでstyled-componentを使う場合はサーバーサイドで入れ込まないとラグが出る可能性がある。
キャッシュ戦略
静的ページは基本的にサーバー負荷を減らすためにSSG(静的ページ出力)を使う。
もし、整合性はあまり求められずAPI取得している部分があればISRで再生成する。
ただ、強い整合性が求められるページの場合はSSRを使う。
で、SSGされる静的ページ自体もブラウザキャッシュでPCに保存されたキャッシュを利用させることが重要。特に画像が重要。できるだけCDNよりもブラウザキャッシュを使うように仕向けて行くことが重要。Vercelを使った場合は、Next.jsではnext/Imageを使えば自動的にキャッシュされるようになる。(ただ利用画像枚数に上限があるので注意)
静的リソースとはいえ、html/js/cssはキャッシュするか確認。修正が入る場合もあるため。(というか既存のキャッシュ設定に倣えばよいが。)、railsなどではビルドごとにダイジェストが付与されてキャッシュされない。
APIなど個人を含む動的情報に関してはキャッシュされてしまうとセキュリティ的にまずいので、それ以外の情報をクライアントサイドでAPI経由で取得するようにする必要がある。(主にログイン後のページ)
CDNとブラウザでなるべく同じキャッシュ設定にするようにする。
Next/Image
Vercelを使った場合は、ハッシュ値を付けてくれて長めのキャッシュでもいける。ただ、外部CDNの画像を読み込む場合はハッシュ値に対応していないので短めのキャッシュが推奨されている。
ただ、現実としてそれは難しいので、長めのキャッシュで適宜CDNをクリアする運用が望ましそう。
画像の遅延読み込み
Vercelならnext/Imageが使えるので特に意識する必要がない。ただ、Vercel以外のCDNだとnext/Imageのloaderを使えば対応可能。cloudFrontは対応していないので別途lazyloadのライブラリを探す必要がある。
ログ
Next.jsでサーバーサイドを動かす場合は必要。JSON LinesというJSON形式でアクセスログを出力するようにするとよい。
国際化
App Routerに対応しているいい感じの国際化ライブラリはないらしい。スクラッチでやってもよい。
ブランチ運用
定常リリースの場合
main→develop→feature→relase→main
緊急リリースの場合
main→hotfix→main
main→developにマージ
テスト
jest、Cypress、strorybook?
監視
これは基本Sentry?New Relic?。sourcemapが欲しい場合はnext.config.jsに設定すればいけるらしいです。
pre-commit
- eslint
- テストコード実行
GitHub
- featureに直コミットは避ける設定。
- PRテンプレートを作成する。
- masterにマージしたら自動的にデプロイされるような設定にするか。
デプロイ先
Vercel?、S3?、EC2?、ECS?、Serverless Framework?それともそれ以外にあるのか?
基本的にISRを使いたい場合はVercelになる。(描画速度が向上するため)
ただ、無理な場合はECSでSSRを使うしかないと思われる。(Cache-ControlできるCDNであればstale-while-reavalidateで疑似的にISR的なことはできる。)
Vercel以外だと自分でCDNを調達する必要性なども発生してくる。
この記事へのコメントはありません。