Open32

「SSG 専用コンポーネントライブラリ」という概念

Kodai MatsumotoKodai Matsumoto

ブログ等の静的サイトを生成したいときに、SPA 開発用の VDOM ライブラリやそれをベースにしたフレームワークを採用する実例が増えている。

しかし、全ページがビルド時に生成でき、かつブラウザ上では SPA としての副作用 (例えば非同期通信をしてその結果に応じてDOMを更新するとか) が必要ない場合、こういった技術選択はオーバーエンジニアリングな気がしてならない。

だから、SSG だけを目的としてビルドスクリプト中で利用されることを想定したコンポーネントライブラリが作れないか、という話

Kodai MatsumotoKodai Matsumoto

テンプレートエンジンを連想するかもしれないが、それだと以下のような要件は満たせないと思われる。

  • 生成したいページを再利用可能なコンポーネントに細かく分解し、それぞれビルドスクリプト中で型安全に再利用できる
  • コンポーネントごとに生成時の副作用を定義して、ビルドスクリプト実行中にそれぞれハンドリングする
Kodai MatsumotoKodai Matsumoto

ここでのコンポーネントは、VDOM ライブラリにおけるそれのようなライフサイクルの概念を持たない。
内容の決定に必要な副作用 (例えばヘッドレスCMSから記事の内容を取得するとか) が完了してビルドスクリプト中の値に一度落とし込まれたら、あとは HTML 文字列に書き出されるのみで、それ以外の状態遷移はしない。

Kodai MatsumotoKodai Matsumoto

このライブラリは開発/ビルド環境でのみ使用しブラウザには直接関与しないので、ビルドスクリプトのための適切な実行環境が構築できるなら JavaScript に限らずどのプログラミング言語で実装してもいいことになる。

Hidden comment
Hidden comment
zakurozakuro

実際の用途だと完全に静的にするという制約は厳しくないですか。
非常にシンプルなテキストサイトなら良くても、ブログとかだとJSでDOMをいじりたい場面は出てくるような

Kodai MatsumotoKodai Matsumoto

仰る通りですね…
この制約は「コンポーネントを安全に再利用するために、コンポーネント間でJSの実行時の依存関係を作るべきではないし、必要があったとしてもコンポーネントの依存関係と対応させるべき」という考えに基づいています。
制約にするのはさすがにやりすぎで、このような考えをドキュメントで強調する程度にするのが良さそうですね

zakurozakuro

SSG するのに nuxt とかは過剰というのは完全同意で、あれはそもそも SPA の副産物として出てきているので、SSG中心で再設計したミニマルなフレームワークとかはあっても良さそう

Hidden comment
Hidden comment
Hidden comment
Kodai MatsumotoKodai Matsumoto

よくよく考えたら「コンポーネント定義」「定義元のソースファイルのパス」「併せて指定されたランタイムスクリプトのパス」を管理しないとビルド時にどのランタイムスクリプトの読み込み用コードを書き出せばいいのかわからなくなる

よってコンポーネント定義・ランタイムスクリプトのパスはソースファイルと1対1対応にして、このフレームワークは Next.js のような CLI ツールとして作るしかない

Kodai MatsumotoKodai Matsumoto

この程度の問題は実装しなくても気づけそうだったのに、PoC 作ろうとしてみないと気づけないこともあるんだなぁと思った