(SSR不要論者のはしくれとして)今までこれっぽっちも気にしてなかった、あのNext.jsです。
ここでいうSSRは、クライアントのリクエストに応じてSSRしてレスポンスを返すこと。
ただ最近仕事で使ったり、副業でも使ってたりする機会があって、一部認識を改めたところがあるのでそれをメモっておく。
静的サイトジェネレータとしてのNext.js
それは、「元来のサーバーレンダリング用ミドルウェアとしてではなく、SSGを目的としたプリレンダリング用ツール」として見れば、実は結構よいのでは?というもの。
コマンドでいうところの`next build && next export`だけを使う前提。
- プリレンダリングで最適化した静的なサイトにしたい
- けど、それぞれのページにはJSを使った処理がある
前者だけの場合は、だいたい`11ty`みたいないわゆる静的サイトジェネレータが検討されるけど、各ページで動かすJavaScriptについては何もしてくれないのがほとんど。
プログレッシブ・エンハンスメントだ〜みたいな割り切りもあるかもしれんけど、リアルワールドではそういうわけにもいかず・・。
かといって、各ページごとに`webpack`などのバンドラを使って自力でやるためには、
- `webpack.config.js`の設定をがんばって書く
- 各ページとの接点は、DOMに`id`振ったりする必要がある
- `hydrate`しないと・・
などなど、面倒よな〜っていうところで、まさかのNext.jsに白羽の矢が立つというわけです。
`next/link`とか`next/router`を使わなければ、Reactをテンプレートエンジンにした静的サイトジェネレータとして使えるやん!という。
(もちろん使いたければ使ってもいいけど。)
各ページごとのJSチャンクの最適化もしてくれるし、静的サイトジェネレータというか、better webpackっていう見方としてもアリなのかも?とふと思った。
不満なところ
静的サイトジェネレータではない
まぁそういうものではないので仕方ないけども。
開発時には自動コンパイルとかのために`next`コマンドを使うことになるけど、このときはサーバーレンダリングでコードが実行される。
つまり、開発時と本番時で、同じ体験にならないという。
基本的にIsomorphicなコードにしろよ感が至るところで感じられるけど、用途的にそれらが制約でしかないのがちょっと面倒。
あと相変わらずHMRはうまく動かないことが多いし、そのくせdisableにするオプションがないのも不満である!
Preactのための設定が必要
`preact/compat`をエイリアスする必要があって、`next.config.js`がちょい太る。
https://github.com/vercel/next.js/tree/canary/examples/using-preact
ちなみに、TypeScriptも併用する場合は、型がハマらなくて困ることがある。
具体的には`next/link`を使うためには、それ用の型を補正しないとダメ。
exportコマンドまだ安定してない説
まず、`export`コマンドのCLI出力が変だったので、PR出してなおした。
あと、これは気のせいかもしれないけど、いちおうメモっておく。
`export`するときは、その出力ディレクトリを毎回消したほうが良い。
さもないと、以前のキャッシュが残ってるみたいな挙動になることがあった気がするので・・。
ちょいちょい融通がきかない
Duplicate meta tags when using Head both in custom document and page · Issue #9794 · vercel/next.js - https://github.com/vercel/next.js/issues/9794
こういうのとか。
他の選択肢はないのか
- Reactが使える
- 複数ページをプリレンダリングできる
という条件だけで見ると、GatsbyとかReactStaticとかも候補にはあがる。
ただGatsbyから漂うCRA感が個人的には好きになれなくて、あれには近寄ってはならぬというささやきが聞こえる・・。
(いやまあこういうのはどうせユースケース次第なんやが)
個人的なお気持ちは、この人のブログに書いてあることと同じような認識。
ReactStaticには期待してたけど、実際に素振りしてみるとなんか思ったとおりにいかず。
- 独自のお作法(というか制約)がすごい多い + 納得感がない
- なんたらテンプレートを使うことがうっすら前提にあり、自分で必要なものだけ、をやるのが大変
SvelteのRoutifyとかと同じ感じかと思ってたのに、ちょっと裏切られた気分。
というわけで、Next.jsを使いたくて選んだというわけではなくて、他にないからという理由だったりする・・。