写点什么

一文看懂 Htmx

作者:天择
  • 2022-10-28
    江苏
  • 本文字数:2177 字

    阅读完需:约 7 分钟

一文看懂Htmx

引言

作为一个前端开发者,使用 React 这类前端框架也有一段时间了。在工作中使用某些工具时间久了,对相关新技术的就麻木了,不会主动思考诸如“为什么代码是这样写的?”,“这是最自然高效的开发方式吗?”这类的问题。


偶然在 JavaScript Weekly 上看到了一篇对比ReactHtmx文章,生词出现了,什么是 Htmx?它为什么要与 React 对比?它与 JSX 有什么关系?在本文中,我基于一些资料的学习试图回答上述问题。

HATEOAS

简单来说,Htmx 提供了一种通过 HTML(而不是 JavaScript)访问各种浏览器特性的方式。


这里的X应该是 extension,是“扩展”的意义。JSX 对 JavaScript 的功能进行了扩展(虽然只是语法级的),Htmx 对 HTML 的功能进行了扩展。


那么到底扩展了什么?回答这个问题,需要先了解HATEOAS的概念。这个词是Hypermedia as the Engine of Application State的缩写,即超媒体驱动应用状态


我们都熟悉超链接(Hyperlink)和超文本(Hypertext)的概念,超媒体(Hypermedia)是对这些概念的扩展,其实就是我们在 HTML 页面上常见的各类多媒体资源的统称,包括视频、音频、图片、文本、链接等等。


我们可以回想下,浏览器端的 Web 应用程序是如何管理应用状态的。比如一个后台用户管理单页面应用(SPA),添加、编辑、删除、排序这类功能是如何在页面上变化和呈现的?一般我们会通过 JavaScript 来实现。


监听控件的 UI 事件后,需要 JavaScript 添加响应代码并定义后续操作。需要请求或者提交数据时,也需要 JavaScript 发起 REST 请求,处理返回的数据,最后渲染到 DOM。这里一个隐含的要求是:请求者需要知道如何使用返回的数据以切换应用状态


比如一个 Server 返回的用户数据的 JSON 对象如下:


{    "account": {        "id": 12345,        "name": "jtzcode",        "status": "active",        "permissions": ["view", "edit"],        "action": "/users/12345/save"    }}
复制代码


这份数据到达后,我们需要通过 JavaScript 或者 CSS 等技术将用户的信息呈现到 UI,也就是光有这些数据,我们仍然不知道怎样呈现 UI,根本原因是数据中没有呈现的逻辑。在上面例子中,我们不知道 UI 怎样通过status的值来呈现,也不知道如何使用action字段里的链接。


那我们能不能直接让 server 返回下一个状态的 HTML 结构呢?这就是 HATEOAS 的理念。每次应用程序状态的变化,不是靠数据驱动,而是页面结构和元素(超媒体)直接驱动。比如上面的例子可能得到类似这样的响应结果:


<div>    <form method="post" action="/users/12345/save">        <label>Name: </label><span>jtzcode</span>        <img src="/users/avarta/12345.png"/>        <button>Edit</button>        <button type="submit">Save</button>    </form></div>
复制代码


这个响应结果可以直接嵌入当前 HTML 页面的某个位置,让应用程序进入下一个状态,即直接通过超媒体驱动,省去了大量 JavaScript 的操作。

开始上手

这里有个官方提供的例子,可以直观感受一下用法:


<button hx-post="/clicked"    hx-trigger="click"    hx-target="#parent-div"    hx-swap="outerHTML">    Click Me!</button>
复制代码


Htmx 更符合声明式的编程语法,有点所见即所得的意思。如上面的声明告诉 Htmx:


当用户单击按钮,向/click的路由发送POST请求,并把返回的内容设置到#parent-div表示的容器中。


看起来这种用法的确可以减少前端开发量,代码简单明确,也确实有商业项目从 React 迁移到 Htmx 实现的案例。不过我觉得在真正在自己的项目里使用前,至少还应该考虑:


  1. 应用规模。上述成功案例只是一个中小规模的应用,对于大型项目,Htmx 能否满足所有业务需求仍需评估。

  2. API 的实现。由于返回结果变为 HTML 格式,那么 API 端可能有更多的渲染工作要做。这方面的技术积累自己是否胜任需要考虑。

  3. 重构成本。如果是已有的项目迁移到 htmx,要根据项目规模、团队结构、业务逻辑评估迁移的 ROI。

延伸话题

你可能说 Web API 返回的数据是什么格式和结构有好坏之分吗(JSON vs Hypermedia)?其实对 REST API 的设计有一个理查森成熟度模型,这个模型的初衷是找到 REST 约束与其他类型 Web 服务的联系。它将设计分层四个层级:The Swamp of POX,Resources,HTTP Verbs,Hypermedia Controls,本文的 HATEOAS 即来源于最后一个层级。


另外,采用 Htmx 的开发方法也符合行为局部性原则(Locality of Behavior,LoB),即开发者应该尽量让一段代码的功能看起来直观(不要让功能定义各处分散)。比如:


<button hx-get="/get">Click Me</button>
复制代码

以及:

$("#btn").on("click", function(){    fetch(...)});<button id="btn">Click Me</button>
复制代码


第一段 Htmx 代码直观地看出点击按钮的行为(发起/get请求),而后一段代码声明按钮控件在一个文件,定义单击事件行为的代码却在另一个文件,就不满足行为局部性约束。

Takeaways

综上,我们可以概括使用 Htmx 开发的要点:


  1. 使用声明式的语法(而不是 JavaScript 脚本)来实现前端的交互。

  2. 使用超媒体(HTML 元素)格式(而不是 JSON)与服务器交换数据。


现在就开启你的 Htmx 探索之旅吧。

参考阅读

  • https://htmx.org/essays/a-real-world-react-to-htmx-port/

  • https://htmx.org/essays/hateoas/

  • https://en.wikipedia.org/wiki/Hypermedia

  • https://htmx.org/essays/locality-of-behaviour/

  • https://htmx.org/essays/hypermedia-driven-applications/

  • https://en.wikipedia.org/wiki/Richardson_Maturity_Model

发布于: 刚刚阅读数: 4
用户头像

天择

关注

还未添加个人签名 2020-09-07 加入

爱看点书的软件工程师 主页:zesi.tech 欢迎交流~

评论

发布
暂无评论
一文看懂Htmx_JavaScript_天择_InfoQ写作社区