自分がNext.jsに拘りNext.jsを使う主な理由は、SSGとかSSRとかというよりはサーバーサイドの処理をNext.jsの中に書きたいから
— 🦄けい©︎:プログラマーアイドル🦄 (@k1_c_) 2024年5月16日
んで、End to Endの型安全とVertical Sliceを徹底したいから
これに限る
UI⇔Application⇔Domain⇔Storageというレイヤーをガッツリ統合し、機能単位での依存を最低限にすることをVertical Sliceと言うらしい。縦の結合は最大化、横の結合は最小化。知らなかった。理にかなっている。
一番型の担保が難しいのがフロントで、結局ブラウザがJavascriptしか動かせない。フロントエンドをReact/Vue等でビルドしたら、Vertical Sliceを実現する選択肢はTypeScriptしかなさそう。RailsはHotwireでサーバーサイド側にフロントを寄せることでFEの責務を最小化し、Vertical Sliceの実現例を見せてくれた。力技だけど。
我はRubyがあまり好きではない。第一言語がJavaだった我には、Rubyのコーディングスタイルが合わない。コンパイルによる型安全が必要だ。ブラウザにはJavascriptの実行エンジンしか積まれないので、結局JavaScriptでDOMDOMするしかない。というわけで、フロントを作るならTypeScript一択。
問題はバックエンドだ。フロントにReactを採用した場合、いい感じにサーバーサイドのロジックが書けるFWがなかった。React自身はUIを構築するライブラリなので、通信やバックエンドのことは原則専門外。そこで非同期通信とレンダリングの仕組みを提供しますよ旦那ってことで、Next.jsが台頭したという認識。他になかった気がする。4年ぐらい前だと。React QueryとかSWRとかも、その類のものという認識。
バックエンドのビジネスロジックを書くものではないとなると、FlutterでRetfrofitでRestAPIクライアント作って呼び出すのと、開発体験としては同じ感覚。アプリならわかるけど、バックエンドのコードが書けないなら面倒なだけでは・・・と。
Page Router時代のgetServerSidePropsを使うのではなく、T3 Stackで提唱されていたtRPCでエンドポイントを自動生成してバックエンドを呼び出すのを見て、お!これええやん!になってトライしたけど、簡単なコードしか書いているものしかなくて、頓挫しちゃった。UIの更新が思いの外面倒だったのと、牛刀をもって鶏を割くことへの違和感が拭えなかった。
MPAの頃だったらFormの入力値を任意のオブジェクトに型変換し、ORMに突っ込んでレコードを作るのは秒殺。Next.jsになった瞬間に、Hooksがどうとか面倒になる。シンプルなAPIを組み合わせて複雑なことをやるとしたら品質がバラつく。なんか違うんだよなぁというツギハギ感が拭えずにいてNext.js以外の選択肢を探した時に、出会えたのだ。マイハニー、Remix(React Router)に。
Remixの Loader / Actionの設計は、自分が望んでいたものだった。Vertical Sliceを実現する最も優れた手段に思え、書き方が単純なので苦労しない。Hooksをゴリゴリ書くこともない。パラレルにリクエストを走らせることをなるべく許容しないRemixのモデルは、受け入れやすかった。
Remixだからではないけど、モノレポ構成にも出来る。アプリ向けのAPIサーバ、一般向けのWebサイト、管理者向けのWebサイトが単一のレポジトリで、エンティティ、DBスキーマ、バリデーションロジックを共有することが出来る。強い、強すぎる。どうしてもこれをやりたい。Gospel Stack Remixでググろう。サンプルレポジトリが置いてあるぞ。
Next.jsの優位性はあんまりよくわからない。ルーティングが簡単なことぐらいしか思いつかない。Reactに詳しくなればなるほど優位性が見えるのだろうか。RSCでコンポーネント単位でBFFやれますって言われても、loaderでJSON返してCacheしたら良さそうに思えてしまう。ピーキーすぎるというか、RSCじゃないと生きていけないケースってどれだけあるんやろ。ストリーミング?
むしろ、SSGやるならNext.jsって印象。SSRならRemixなのではと。実際Remixで書いてみると、Vertical Sliceが素直に実現できる。これ以外でWebアプリケーション書きたくないンゴ。