2026/01/26
レンダリング!

元々このサイトはNext.jsで生成される静的サイトで、以下のようになっていた。

  • Next.jsによるStatic Site Generation
    • Next.jsのライフサイクル
      • getStaticPaths
        • [yyyy]_[mm][dd].jsなファイルの一覧を取得
          • 中身はexport default { title: string, content: HTML }なJSX(としてHTMLを持つJSオブジェクト)
          • ただし、ここでは中身は読まず、nodeのfs.readdirでファイル名のみ集める
        • Next.jsのDynamic Routesposts/[yyyy]/[mm]/[dd]なパス(とページ)を生成
      • getStaticProps
        • [yyyy]_[mm][dd].jsなファイルの一覧を取得(同上)
        • 各ファイルの情報をシリアライズ可能なJSオブジェクトとして用意する(つまりJSX等を渡せない)
      • Next.jsのpage / Reactのライフサイクル
        • JSXとしてHTMLを持つ各ファイルをdynamic importしてページを作る

いろいろと改善はしたけど、2022/04/23 JSX as dataと2021/01/02 Next.jsとPHPと私で書いたときとほぼ同じ。App Routerには移行せずPage Routerのまま。十分楽しんだし、そろそろNext.jsから離れるか、ということで書き換えて、以下のようになった。

  • nodeで実行
    • tscでJSXと.tsをESモジュールに変換
      • [yyyy]_[mm][dd].jsなファイルの一覧を取得
      • JSXとしてHTMLを持つ各ファイルをdynamic importする
      • renderToStaticMarkupで静的なHTMLを出力する
        • Reactでページを作る

実行順じゃなくて依存ツリー(?)なので注意。Next.jsのライフサイクルから解放された結果、JSX(を含むJSオブジェクト)のdynamic importを早めに行えるようになり、Reactのライフサイクル内では非同期実行を含まなくなった。あれ?(tscのコンパイル時にはdynamic importは実行されてないのに)コンパイル後のESモジュールがJSXをimportできるのは何故なんだろう。何か勘違いがありそう。ちなみに、renderToStaticMarkupはレガシーなAPIらしく、prerenderToNodeStreamだとサスペンスの解決まで待てるから非同期処理も含められて、かつ、「クライアントで React をまったく実行したくない場合」としてhydrationしない場合への言及もあるから、たぶん移行できるはず。そのうちやる。

HTMLで書きたいが、そのままでは辛い。だからJSX。Reactじゃなくていいのかもしれないけど、そこで道を踏み外すのは辛そうだし十分に好きだからReact。そして静的サイトが欲しくて、かつ、面白そうだったからNext.js。という流れの最後を差し替えたのが今回。いろいろと整理した後だったから割とすんなり。動いていないはずのCSSがNext.js版では動いていることが分かり、謎が解けないから仕方なく正しいものに直したりはした。あとTypeScript関連でも似たような謎があった気がする。

Live Reload的なものが失われたから、次はそれをどうにかしたい。そういうライブラリを使えばいいんだけど、依存を減らしたいから自分で書きたくて、Server-Sent Eventsを使ってどうにかする。開発用のサーバを書く感じ。最終的にこの部分はSwiftで書いてもいいかもなあ。

日付
タイトル