HonoのJSXでPolyglotなSVGからQuineでイルミネーション

  • 投稿日:
  • by
  • カテゴリ:

こんにちは。OSS珍百景として紹介されたPRの作者の天野です。

今年は以下のあたりを中心にHonoにコミットしました

  • v3.12.0
    • CSRF Protection Middleware
    • css Helper
  • v4.0.0
    • Client Components
  • v4.5.0
    • Combine Middleware
    • React 19 Compatibility

この記事ではこれらの機能の実現に使った内部の機能に触れつつ、PolyglotなSVGを使ってHonoのJSXの表現力を試してみたいと思います。

できたもの

hono-polyglot-svgができました。以下のSVG画像ファイルはそのまま出力するとオリジナルのHonoのアイコン画像が表示されますが、HonoのJSXを経由すると、色を変えつつ自分自身を出力するQuineなSVG画像として出力されます。

  • http://localhost:3000/static/hono.svg : そのまま出力
  • http://localhost:3000/static/hono.svg?eval=1 : JSXで処理して出力

です。以下のような結果になります。

解説

コールバックから書き換える

HonoのJSXの文字列化では、要素の属性値や内容としてPromise<string | String>を返すことができ、useを使うことなしにasyncな関数コンポーネントから簡単に文字列の結果を出力することができます。さらにここでStringに対してisEscapedcallbacksを指定することで、出力される際の挙動をコントロールすることができます。

この特殊なStringを作成するためには、通常は"hono/utils/html"からエクスポートされているraw()を使いますが、使わずに作成することもできます(内部の構造は今後変更される可能性もあるので、推奨はされませんが)。

callbacksに指定した関数が呼び出されるタイミングは、単純な文字列化以外にもrenderToReadableStream()を使ってレスポンスを返す前後のタイミングなど、いくつかあるのですが、ここでは深入りせず単純な文字列化を前提とします。以下のようにしてcallbacksに指定した関数で渡されたbufferの値を変更すると、出力結果を書き換えることができます。

これが今回の、処理するたびにSVG画像の色が変わる挙動の仕組みです。Honoに実装された機能の中では「css Helper」でのstyle要素の埋め込みや、「React 19 Compatibility」でのtitle要素のhoistingで使われています。

(無駄に)Combine Middlewareを使う

「同じパスのURL」でありながら「処理方法(クエリストリングで指定)によって結果が変わる」ということを表現したかったので、Combine Middlewareのsome()を無駄に使って宣言的に書いてみました。以下のように書くと「evalが指定されたときにのみevalSvgMiddlewareを適用する」という挙動になります。

今回の例だと無理矢理感がありますが、hono.devのドキュメントでは認証と組み合わせた実用的な例も紹介されています。

解説は以上になります。

今年の振り返り

さて今年といえばHonoにとってはHono Conference 2024 - Our first stepの開催が一番のイベントだったと思います。(参加レポート書いてなかったですが。)コミッターの方やコメントをしてくれる方の顔を見られて、どんな話し方をするのかを知ることができたのは嬉しかったです。議論が円滑に進むかどうかはまた別の話だとしても、「GitHubのコメントが当人の声で再生できるようになる」というのは、やはりよいものだと思いました。

この記事について

これは Hono Advent Calendar 2024 のシリーズ 1の6日目の記事です。シリーズ 2もあるようなので、引き続きよろしくお願いします!