- 人々は、htmxがSPAにおいてWebを救うかのように語っている
- htmxの作者Carson Grossは、この力学を「ヘーゲルの弁証法」としてウィットを交えて説明している:
- 定立(thesis): 従来のMPA
- 反定立(antithesis): SPA
- 総合(synthesis): ハイパーメディアベースのインタラクティブな島々で構成されたアプリケーション
- しかし私はそこに至らず、以前に「htmxでSPAを作った」
- シンプルなToDoリストアプリのPoC
- ページが読み込まれると、以後はサーバーと通信しない
- すべてがクライアント側でローカルに処理される
- htmxがネットワーク越しのハイパーメディア交換の管理に焦点を当てているなら、これはどうやって動くのだろうか?
- 1つのシンプルなトリック: 「サーバーサイド」コードがService Workerで実行される
サービスワーカー
- Webページとインターネットの間でプロキシとして動作する
- ネットワークリクエストを横取りして操作できる
- リクエストの変更、オフライン用のレスポンスのキャッシュ、ブラウザの外にリクエストを送らずに新しいレスポンスを生成することが可能
- 最後の機能がこのシングルページアプリの中核
- htmxでネットワークリクエストを送ると、サービスワーカーがそれを横取りする
- その後、サービスワーカーがビジネスロジックを実行し、新しいHTMLを生成する
- htmxが新しいHTMLをDOMに差し替える
既存のSPAに対する利点
- サービスワーカーはストレージとしてIndexedDBを使う必要がある
- これにより、ページ読み込みをまたいで状態を保持できる
- ページを閉じて戻ってきても、アプリがデータを覚えている
- これは、このアーキテクチャを選ぶことで「無料」で得られる副次的な利点
- オフラインでも動作させやすい
欠点
- 開発者ツールのサポートが貧弱
console.logが断続的に欠落する
- サービスワーカーがインストールされているかどうかの表示が信頼できない
- FirefoxでESモジュールがサポートされていない
- すべてのコードを単一ファイルに入れなければならない
- 全体的な開発体験が「楽しくない」
それでもhtmx SPAはうまく動く
実装の詳細
- ベースとなるHTMLは、シングルページアプリの空の骨組み
<body>タグがhtmxを使ってアプリ本体をセットアップする
hx-boost="true": htmxに対し、フルページナビゲーションなしでリンククリックやフォーム送信のレスポンスをAjaxで置き換えるよう指示する
hx-push-url="false": htmxがリンククリックやフォーム送信に応じてURLを変更しないようにする
hx-get="./ui": ページ読み込み時に/uiからページを取得して差し替えるよう指示する
hx-target="body": 結果を<body>要素に差し替えるよう指示する
hx-trigger="load": ページ読み込み時にこれらすべてを実行するよう指示する
/ui エンドポイント
- アプリの実際のマークアップを返す
- その後、htmxがリンクとフォームを制御してインタラクティブにする
- サービスワーカーがExpressスタイルのライブラリでリクエストルーティングを処理する
setFilterとlistTodosは、IDB Keyvalをラップしたシンプルな関数
Appコンポーネントは、フィルタフォーム、ToDo一覧、追加フォームで構成される
/todos/add エンドポイント
- ToDoを保存した後、UIを再レンダリングしたレスポンスを返す
- htmxがレスポンスをDOMに差し替える
Todo コンポーネント
- チェックボックス、削除ボタン、ToDoテキストで構成される
- チェックボックスは
/todos/${id}/updateへのリクエストをトリガーする
- 削除ボタンは
/todos/${id}への削除リクエストをトリガーする
- ToDoテキストには「normal」と「editing」の2つの状態がある
- htmxがダブルクリックイベントを受け取る
/ui/todos/${id}?editable=trueをリクエストする
- サービスワーカーが
<input>を含むTodo HTMLを返す
- htmxがレスポンスのHTMLで現在のToDo項目を差し替える
要約
- 技術的には動作する
- 良いアイデアだろうか? 本当にハイパーメディアベースのアプリの到達点なのだろうか? Reactを捨ててこれで作るべきだろうか?
- 完全にローカルなアプリでは、htmxの間接性は解放感よりも負担に感じられる
- ほとんどのアプリは完全にローカルではない
- 「インタラクティブな島々(islands of interactivity)」パターンのほうが、「サーバーサイド」コードをサービスワーカーと実サーバーに分割するより良いと考えている
- ハイパーメディアで完全にローカルなシングルページアプリを構築する様子を示すための実験的な試みだった
まだコメントはありません。