さわだ見聞録

はじめに

さわだです。
おおよそ1年ぶりの更新となります。

このブログが抱える問題点は山積みでした。

  • ダサい
  • Nuxt 2で動いてる
  • ダサい
  • ダサい

ということで、Nextの勉強がてらブログを作り直してみました。

使った技術

リポジトリ を見てもらったほうが早いかも?

  • Next.js v13
    • 今回は調子に乗って app router で実装してみたが、その利点を活かしきれず…
  • MUI v5
    • NextのUIフレームワークの王道だと勝手に思っている。これ採用しておけばまあ困ることはないという過信までしている。
  • microCMS
    • リポジトリにMarkdownをプッシュして、 nuxt-blog で読み込む というアナログな手法をとっていたが、リポジトリで管理するのはコードだけにしたいなあと思い採用。
  • react-markdown
    • とりあえずぱぱっと動くものを作ろう〜 のノリで採用。もうちょっと細かい制御をするときは、 unified を使う方が良いのかもしれない。
  • highlight.js
    • prism とかなり迷ったが、細かいこと考えずに多機能になってくれるこちらを採用。多分今後も変わらない。

やったこと

詳しく見たい人は コミット を見てね。

必要そうなコンポーネントの作成

ヘッダーとか、プロフィールとか。
ここでちゃんと全コンポーネント洗い出して設計しておけばこのあと苦労しなかったんだろうなあ と今になって思います。

storybook の導入

前々から気になっていたので、勢いで導入。
あーでもないこーでもないと悩んでる間に消えてた。どうして?

今後新規コンポーネントを作る機会があれば導入しなおしたい…

API 実装

サーバサイドから microcms-js-sdk を用いて microCMS へ記事を取りに行くよう実装。
このときはクライアントサイドから Next.js の API routes に対して SWR を通じて fetch してもらう方針だったが…次項へつづく。

自分の気がコロコロ変わる + 考慮漏れ のダブルパンチでインターフェースがコロコロ変わって大変でした。
最終的には openAPI の定義書を書いて、それに沿って実装しました。設計、大事。大切。

SSR 対応

クライアントサイドで fetch する際、結果が返ってくるまでの間にローディングアニメーションを表示することができます。
が、ブログを観るたびに、各ページをレンダリングするたびに、あのぐるぐるが映るのナンセンスじゃないですか?
ということで、サーバサイドで API routes への fetch も済ませて、とってきた記事の内容を表示するよう修正。

わかったこと

pages router と app router の違い

そもそも pages router も深く触ったわけじゃあないんですが、 pages router と比べて変わるところは多々ありました。
なかでも大きく変わったのが、コンポーネントや各ページの扱い。

pages router では、どこまでをサーバサイドで担当して、どこからをクライアントサイドで担当するのかを明示的にすることができました。
これが app router を使うようになると、明示的にしない限りは すべてサーバサイドで担当するコンポーネントとして扱われる ので、最初は結構困惑します。

まだまだ挙動を理解しきれていないですが

  • レンダリング時に要素の内容が決まったり、レンダリング後に要素の数が変わったりするものは、サーバサイドコンポーネントとして扱うことはできない
    • 動的な要素はサーバサイドで静的にレンダリングしようがないため
    • 'use client' 等でクライアントサイドでレンダリングすることを明示的にしてやる必要がある

と解釈しておきます。
もっと細かい違いに気づいたり、より正しい表現が思いついたときは、また別の記事に書きます…

そして、これらに悩むくらいだったら pages router で実装するのも場合によってはアリかなーと思います。
pages router がサポート終了になるわけでもないし。

ただ「コンポーネントをいっぱい作ることになりそう!」だとか「責任分担をしっかり意識するコーディングがしたい!」だとかいうニーズの場合には圧倒的に app router をおすすめします。
私が趣味の範疇で書いてる分には pages router でもいいかなー…

わからなかったこと、改善点

microcms-js-sdk のエラーハンドリング

こういうライブラリって独自でエラーの型が定義されてて、 try-catch とかするときに型分別しません?
microcms-js-sdk の実装をチラッと覗いた限りではそういった類いのものが見当たらなかったため、うまいことエラーハンドリングできませんでした。
私が見落としているだけなんだろうか…?仮に本当にないんだとしたら、型定義してほしいな…

Next.js のエラーハンドリング

ほぼできていないと言っても過言ではないでしょう。
現在はエラーが発生した際にページが真っ白になってしまいます。

本当はステータスコードに応じて HTTP Cats の画像が表示されるエラーページを作りたかったんですが、Next.jsも独自のエラー型ってないっぽい…?
( Nuxt.js で実装したときは型定義があったので、上記の実装が大変楽だった)
やろうとすると「エラーコードがある型なのか確認して、あった場合は…」みたいな書き方をせざるを得ないなあと思ってしまいました。

最悪の場合、本当に型定義がなかったとしても上記の泥臭い方法で対応自体はできるので、近い将来改善します…

Markdown 内の HTML をパースして表示

Markdown のお作法的にどうなん?という気持ちがかなり強いですが…
Twitterの埋め込みスクリプトを表示させたい場合があるので、この対応はしたいです。

「使った技術」 の react-markdown でも少し触れましたが、 unified であれば実現できそうでした。
これは今後変えることでしょう…

さいごに

これから Next.js と MUI に触れる機会をどんどん増やしていく予定なので、わからなかったこととか改善点は克服していきたい…!

それでは、また気が向いたときに〜

プロフィール

さわだ

さわだ

ひまなときにかきます。