世界を動かす技術を、日本語で。

Phoenix LiveView 1.2

概要

  • LiveView 1.2.0 がリリースされ、mix.exsのバージョン更新のみで移行可能
  • Colocated CSS がHEExテンプレート内で利用可能に進化
  • 新しい @scopeルール によるCSSスコープ設定が技術的にサポート
  • デフォルトでスコープは無効、独自実装やカスタム戦略が必要
  • その他にも 小規模な改善 や新機能が多数追加

LiveView 1.2.0 アップデート方法と主な新機能

  • LiveView 1.2.0 へのアップデートは、mix.exsの{:phoenix_live_view, "~> 1.2.0"}にバージョン指定を変更し、依存関係を再取得するだけで完了
  • Colocated CSS 機能追加により、HEExテンプレート内で直接CSS記述が可能
    • 例: <style :type={MyApp.ColocatedCSS}> ... </style>のように記述
    • :type属性により、タグ内容がコンパイル時にphoenix-colocatedフォルダへ抽出、TailwindやEsbuildなどのバンドラで処理
  • Colocated JS と同様の仕組みで、CSSもテンプレートごとに分離管理

CSSスコープ設定と@scopeルール

  • @scopeルール により、特定コンポーネント内だけにCSSを適用可能
    • 例: @scope ([phx-css-foo]) to ([phx-r]) { p { font-weight: bold; } }
  • phx-r属性 がテンプレートのルート要素に付与され、スコープの範囲を明示
  • phx-css- *属性がColocated CSS使用時のルート要素に自動付与
  • slot使用時、スロット内要素も独立したphx-r属性付与でスコープを明確化

HEExテンプレートのコンパイル方式変更

  • Colocated CSS対応のため、 HEExテンプレートのコンパイル処理を分割
    • トークナイズとパースを分離し、マクロコンポーネント(Colocated CSS/JS)も柔軟に処理
    • テンプレートコンパイルとフォーマット間のコード重複も解消

デフォルトスコープ未対応と今後の対応

  • LiveView 1.2 では@scopeによるスコープCSSはデフォルト無効
    • 理由: 2026年6月時点で主要ブラウザで@scope未対応
  • 独自の @behaviour を実装し、カスタムスコープ戦略の導入が可能
  • 公式ドキュメントには@scopeの実装例あり、早期導入も選択可能

その他の小規模な改善点

  • Phoenix.LiveView.HTMLFormatter.TagFormatter ビヘイビアで、HEEx内の<script><style>タグを任意のツール(例: prettier)で整形可能
  • Phoenix.LiveView.JS構造体 がpush_event送信時に自動エンコード(Jasonまたは組み込みJSON利用時)、JS.to_encodable/1で手動エンコードも可能
  • HEExデバッグ注釈 をモジュール単位で@debug_heex_annotationsや@debug_attributesで設定可能
  • テスト警告 をカテゴリごとに設定可能
  • JavaScriptクライアント のドキュメントを分離、詳細はchangelog参照

フィードバックとサポート

  • フィードバックは Elixir forumBlueSky で受付
  • バグ報告は GitHub Issue で受付
  • Dashbit によるスポンサーシップに感謝

Happy coding!

Hackerたちの意見

LiveViewはすごく新鮮で、特に最近のNextJSの複雑なコードに比べると最高だね(特別なホスティングが必要で、遅いし、キャッシュやバックグラウンドワーカー、認証などの専用の有料サービスをたくさん追加しないといけない)。ElixirとPhoenixはそれを最初から提供してくれるのに。

Phoenixフレームワークには、最初からどんなキャッシュが提供されてるの?

LiveViewが大好きなんだ。最近クライアントのプロジェクトで使ってて、すごく…リラックスできる。めっちゃ好きだよ。

specialized hosting どういう意味?私のプライベートなnext.jsフルスタックアプリは、Kubernetesクラスター上でDocker化されて動いてるし、認証にはauth0を使ってるよ。だって、keycloakとか今流行りのDocker化された認証を動かすのが面倒なんだもん。

ASP.Net/Blazorと比べて、どんな利点と欠点があるの?

BEAM仮想マシンについて。軽量で隔離されたプロセス、メッセージパッシング、スーパーバイザー、ホットなランタイムのイントロスペクション、障害の隔離は後から追加されたライブラリじゃなくて、基盤そのものなんだ。アプリを作るなら、以下の要素が必要になるよね:+ 多くの同時ユーザー + リアルタイムUI + バックグラウンドジョブ + ワークフロー + 状態を持つセッション + 分散イベント + 障害の隔離 + 「このアプリは数ヶ月間動き続けるべき」 そういう場合は、BEAMの上に構築されたものが欲しくなるよ。

要するに、LiveViewはウェブ専用だよ。LiveViewをネイティブにする試みはあったけど、すごく難しいし、今のところ(私の知る限り)全部失敗してる。最近考えてたんだけど、carsandbids(Doug DeMuroの車オークションサイト)はBlazorを使ってるみたいだね(少なくとも私が見た限りでは)。これがBlazorの最大の利点の一つだと思う—ネイティブアプリとウェブアプリの両方を作れるのに対して、LiveViewは絶対にそうじゃないから。Microsoftがそれを支払えるから(または少なくとも大規模なインフラをサポートできるスポンサーがいるから)。それに、これは解決するのがすごく難しい問題なんだ。膨大な資金が必要で、AndroidとiOSのSDKを理解できる大きなチームや、純粋なエンジニアリングの課題に取り組む人を雇うための資本が必要だから(だからMSやMetaができるんだ)。エンドユーザーは、LiveView、Blazor、React、Java、SwiftUIなどで作られているかなんて気にしないし、長期的にそれを実現できる企業のリストは非常に少ない。OTPを実装したり、他の言語やランタイムに意味のある形でトランスパイルするのも簡単じゃない問題だし。Erlang、BEAM、OTPは特定の問題のために非常に特異な方法で一緒に作られたもので、もし一緒に開発される必要がなかったら、死んだ言語、ランタイム、プラットフォームになってたはずだよ(ちなみに、全然そんなことはないけどね)。

多くの人がliveviewを好きだよね。逆にblazorを嫌う人も多いし、Microsoftがそれを「新しいwebforms」として扱ってるせいで評判が悪くなってる(実際、レガシーwebformsプロジェクトの公式な移行パスになってる)。blazorの利点は、C#と.NETエコシステムだと思う。もし私が選ばなきゃいけないなら、ほとんどの他の技術よりblazorを選ばないかな。悪い経験があるからね。技術的にはすごく似てるけど、開発体験が大事だと思う。

CSSの統合についてはあまり気に入ってないな。それに最近リリースされたJSも一緒に使うやつ。便利ではあるけど、逆に大混乱になる可能性もあるからね。Rails 2.xの時みたいで、rjsとか使ってたフロントエンドのコードをデバッグしたり修正するのがほぼ不可能になってた。コードベースの中にバラバラなJSのスニペットが散らばってて、見つけるのが大変だったから。Phoenixチームがすごく努力してるのは分かるし、実際にうまくいくことを願ってる。でも、CSSファイルと分離されたJSがちゃんと動くから、使うのにはちょっと躊躇しちゃうな。多分、試すまでに数年待つことになるかも。

正直、それはJSフレームワークからコピーされたものだよね。君に同意するけど、時々スコープ付きCSSがあると便利だと思う。

colocated JSが結構好きだな。コンポーネントの中に「フック」コードを定義する方が好きだ。悪用することもできるけど、単に「JSファイルを書くのを避けるため」にテンプレートにcolocated JSを入れることは絶対にしないけど、email_inputコンポーネントのすぐ隣にemail_validator.jsのコードを置くのはいいと思う。モジュール名を継承することが基本的に強制されるから、MyAppWeb.Admin.Components.EmailValidatorMyAppWeb.Admin.Componentsモジュールにいるのは明らかだしね。実際にどれくらいJSを使うかにもよると思うけど、私のライブビューアプリのほとんどは「ここかそこか」で何かを強化したり、ちょっとしたDOMの操作をするために使ってる。もしどこでもReactコンポーネントを立ち上げて、他の既存のJSコードが山ほどあるなら、あんまり良くないかもね。

Surface、Vue、Svelteはずっとcolocated cssとjsを使ってるよね。これのおかげで、メンテナンスしやすいコードになるし、tailwindみたいな解決策に頼らなくても済む。グローバルスタイルはまだグローバルでいられるけど、コンポーネントレベルのスタイルはコンポーネントレベルに留まるんだ。

Hacker Newsで議論の続きを見る