Phoenix LiveView 1.2 Release Notes

Phoenix LiveView 1.2 专注于通过在 HEEx 模板中直接实现 CSS 共存(colocation)来提升开发者体验,这镜像了之前为 JavaScript 引入的功能。此版本包含对 HEEx 编译器的重大架构变更,以支持这些功能。

Colocated CSS in HEEx Templates

LiveView 1.2 允许开发者使用带有特定 :type 属性的 <style> 标签直接在 HEEx 模板中定义 CSS 样式。这种方法使得样式可以与它们旨在影响的 HTML 一起定义。

Implementation and Build Pipeline

使用 :type={MyApp.ColocatedCSS} 定义的样式会在编译时被提取到 _build 目录下的一个特殊的 phoenix-colocated 文件夹中。这些提取出的样式随后会被项目的现有 CSS 流水线(例如 Tailwind CSS 或 Esbuild)处理,从而确保共存样式被集成到最终的打包 CSS 中。

CSS Scoping and the @scope Rule

为了防止共存样式泄露到其他组件中,LiveView 1.2 引入了一种作用域机制。这是通过在渲染的 HTML 中添加唯一属性来标识模板边界实现的。

  1. Root Tag Attribute: 通过在 Phoenix LiveView 配置中配置 root_tag_attribute: "phx-r",LiveView 会为模板的所有最外层元素添加一个 phx-r 属性。
  2. Unique Component Attributes: 使用作用域 CSS 的组件根元素也会收到一个唯一的 phx-css-* 属性。

这些属性允许使用现代 CSS @scope 规则来专门针对组件的根部并限制选择器。例如,像 @scope ([phx-css-foo]) to ([phx-r]) 这样的规则可以确保只有该特定组件边界内的元素会受到影响。

Scoping Availability

虽然提供了作用域的基础设施,但 @scope 实现并未在 LiveView 1.2 中默认启用,因为截至 2026 年 6 月,@scope CSS 规则尚未在所有浏览器中得到普遍支持。相反,LiveView 提供了一个 @behaviour,允许开发者实现自定义的作用域策略,或者选择加入 @scope 实现以进行早期采用。

HEEx Compilation Architecture

为了支持 CSS 和 JS 的共存,Phoenix 团队彻底重构了 HEEx 编译过程。编译现在被分为两个截然不同的步骤:标记化(tokenization)和解析(parsing)。这一架构变更简化了宏组件的处理,并减少了模板编译与格式化之间的代码重复。

Additional Improvements in 1.2

LiveView 1.2 带来了几项提升开发体验的改进:

  • HTML Formatter: 一个新的 Phoenix.LiveView.HTMLFormatter.TagFormatter 行为允许开发者使用外部工具(如 Prettier)来格式化 HEEx 模板中的 <script><style> 标签。
  • JS Struct Encoding: Phoenix.LiveView.JS 结构体现在通过 push_event 使用 Jason 或内置的 JSON 模块发送时,会自动进行编码。开发者也可以使用 JS.to_encodable/1 手动进行编码。
  • Debug Annotations: HEEx 调试注解现在可以基于每个模块进行配置,使用 @debug_heex_annotations@debug_attributes
  • Testing: 测试警告现在可以按类别进行配置。
  • Documentation: JavaScript 客户端现在有了自己专门的文档。

Community Perspectives

社区讨论突显了对共存资产(colocated assets)的复杂反应。虽然一些用户发现这与现代 JavaScript 框架相比是“一阵清新的空气”,但也有人担心共存 JS 和 CSS 可能会导致代码库变得混乱,并引用了 Rails 2.x 的过往经验。一位用户指出,他们之前在 Surface UI 中使用过类似的功能,并很高兴看到它被集成到 LiveView 主线库中。

Sources