Phoenix 1.6.0 发布

发表于 2021 年 8 月 26 日,作者 Chris McCord


我很高兴地宣布,Phoenix 1.6.0 紧随 LiveView 0.16 版本发布后发布!此版本带来了许多重大新增功能、生活质量改进、错误修复以及一些弃用。您可以使用以下命令获取 rc phx.new 生成器

$ mix archive.install hex phx_new 1.6.0

新的身份验证和邮件生成器

感谢 José Valim 和 Aaron Renner 的努力,Phoenix 1.6 提供了一个新的 phx.gen.auth 命令,用于在您的应用程序中启动完整的身份验证解决方案。您可以在 José 在 Dashbit 博客上的文章 中阅读有关身份验证生成器背后的设计决策。Phoenix 现在还默认包含 swoosh 以支持邮件发送,以及一个新的 phx.gen.notifier 任务,用于生成一个发送电子邮件的通知器,以及用于本地开发的开发邮箱。

新的 LiveView HEEx 引擎

除了生成器之外,Phoenix LiveView 0.16 刚刚发布了一个新的 HTML 引擎 (HEEx,~H) 用于支持 HTML 的模板编译,您将在所有生成的凤凰 HTML 文件中看到它(phx.new, phx.gen.html, phx.gen.live, etc)。新引擎不仅强制执行正确的 HTML,而且还提供语法便利来渲染组件,例如 <.form for={@user} id="user-form">。这个新引擎要感谢 Marlus Saraiva 的出色工作,他从他的优秀库 Surface 中提取了它,该库构建了 Phoenix LiveView 之上的功能。我们期待看到每个项目在不断创新和分享我们的工作时如何继续创新,以实现新的引擎功能。有了 HTML 引擎和函数组件,我们为一个充满活力的共享和可重用组件生态系统奠定了基础。您可以关注 HEEx 路线图 以了解我们的功能计划的最新信息。现在,以下是来自 Phoenix LiveView 文档的 HEEx 的简要概述,以便让大家了解最新情况

注意:HEEx 需要 Elixir >= 1.12.0 才能在错误消息中提供准确的文件:行:列信息。早期的 Elixir 版本将可以工作,但会显示不准确的错误消息。

HEExEEx 的一个支持 HTML 和组件的扩展,它提供了

  • 内置的 HTML 属性处理
  • 用于注入函数组件的类 HTML 表示法
  • 对模板结构进行编译时验证
  • 能够最大程度地减少通过网络发送的数据量

示例

~H"""
<div title="My div" class={@class}>
  <p>Hello <%= @name %></p>
  <MyApp.Weather.city name="Kraków"/>
</div>
"""

语法

HEEx 建立在嵌入式 Elixir (EEx) 之上,这是一个模板语法,它使用 <%= ... %> 来插值结果。在本节中,我们将介绍 HEEx 模板中的基本结构及其语法扩展。

插值

HEExEEx 模板都使用 <%= ... %> 来在 HTML 标签的主体中插值代码

<p>Hello, <%= @name %></p>

同样,条件和其他块 Elixir 结构也得到支持

<%= if @show_greeting? do %>
  <p>Hello, <%= @name %></p>
<% end %>

注意,我们没有在结束标签中包含等号 =(因为结束标签不输出任何内容)。

HEEx 和 Elixir 的内置 EEx 之间有一个重要的区别。HEEx 使用特定注释来插值 HTML 标签和属性。让我们看看。

HEEx 扩展:定义属性

由于 HEEx 必须解析和验证 HTML 结构,因此使用 <%= ... %><% ... %> 进行的代码插值仅限于 HTML/组件节点的主体(内部内容),不能应用于标签中。

例如,以下语法无效

<div class="<%= @class %>">
  ...
</div>

改为

<div class={@class}>
  ...
</div>

对于多个动态属性,您可以使用相同的表示法,但无需将表达式分配给任何特定属性。

<div {@dynamic_attrs}>
  ...
</div>

{ ... } 内部的表达式必须是关键字列表或包含表示动态属性的键值对的映射。

HEEx 扩展:定义函数组件

函数组件是使用 Phoenix.Component 模块作为纯函数实现的无状态组件。它们可以是本地的(同一个模块)或远程的(外部模块)。

HEEx 允许使用类 HTML 表示法直接在模板中调用这些函数组件。例如,一个远程函数

<MyApp.Weather.city name="Kraków"/>

本地函数可以用一个前导点调用

<.city name="Kraków"/>

其中组件可以定义如下

defmodule MyApp.Weather do
  use Phoenix.Component

  def city(assigns) do
    ~H"""
    The chosen city is: <%= @city %>.
    """
  end

  def country(assigns) do
    ~H"""
    The chosen country is: <%= @country %>.
    """
  end
end

通常最好将相关的函数分组到一个模块中,而不是在许多模块中包含一个 render/1 函数。您可以在 Phoenix.Component 中了解更多关于组件的信息。

新的 LiveView 服务器生命周期钩子

感谢 Phoenix 团队的 Michael Crumm 的工作,LiveView 0.16 引入了 on_mountattach_hook 钩子,它们提供了一种机制来利用 LiveView 生命周期中的关键阶段。这允许开发人员在必要时绑定/更新分配、拦截事件、补丁和常规消息,以及注入通用功能。钩子可以附加到以下生命周期阶段中的任何一个::mount(通过 on_mount/1)、:handle_params:handle_event:handle_info

新的 LiveView live_session 用于优化导航

LiveView 0.16 还引入了路由器中的 live_session 宏,用于将实时路由分组在一起。这允许通过实时重定向进行的所有实时导航都通过现有的 websocket 连接进行。这避免了对服务器的额外 HTTP 往返行程,并提供了极其快速的导航体验,因为不再需要 HTTP 握手。 live_session 还允许提供一个生命周期 on_mount 钩子,允许 LiveView 共享通用代码路径,例如身份验证,而无需在每个模块上指定钩子。

使用 esbuild 无需节点和 webpack 的资产构建

除了新的 HTML 引擎之外,我们还在 phx.new 项目生成器处理资产的方式上做出了重大改变。我们完全放弃了 webpack 和节点。您现在可以在没有系统上安装节点或 npm 的情况下构建您的 js 和 css 包!多年来,Phoenix 最大的支持问题一直围绕着节点工具、重大变化,以及通常不必要的变动。通过使用 esbuild,项目可以使用可移植二进制文件进行跨平台、无依赖项的资产构建,这种构建速度快且只需工作/tm。五年后,您不应该害怕对 js 或 css 文件进行一些更改,并发现您的工具在您下面已经坏了。高级前端用户可以继续利用适合他们工作流程的 webpack 工具,但我们希望这种无依赖项解决方案能够围绕资产带来更多“安心”,符合 Phoenix 的口号:)。对 DockYard 的 Brian Cardarella 和 Phoenix 团队的 Max Veytsman 表示衷心感谢,他们通过我们的 js 选项进行了探索并试验了解决方案,以及 Wojtek Mach,他负责领导可移植二进制 esbuild 提取工作。还要感谢 José 为各种工具编写了一些 go 和 JavaScript PR,用于处理混合关闭而没有僵尸进程。

此版本还将 Phoenix.View 提取到它自己的库 phoenix_view 中,因此非 Web 用户可以使用 Phoenix 的视图渲染,而无需引入所有 Phoenix。

与往常一样,分步升级指南可以在这里找到

https://gist.github.com/chrismccord/2ab350f154235ad4a4d0f4de6decba7b

您还可以查看 完整的变更日志 以了解更多详细信息。

如果您需要帮助,请在 elixir slack 或论坛上找到我们。祝您编码愉快!

–Chris