一文看懂 Htmx
引言
作为一个前端开发者,使用 React 这类前端框架也有一段时间了。在工作中使用某些工具时间久了,对相关新技术的就麻木了,不会主动思考诸如“为什么代码是这样写的?”,“这是最自然高效的开发方式吗?”这类的问题。
偶然在 JavaScript Weekly 上看到了一篇对比React
和Htmx
的文章,生词出现了,什么是 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 对象如下:
这份数据到达后,我们需要通过 JavaScript 或者 CSS 等技术将用户的信息呈现到 UI,也就是光有这些数据,我们仍然不知道怎样呈现 UI,根本原因是数据中没有呈现的逻辑。在上面例子中,我们不知道 UI 怎样通过status
的值来呈现,也不知道如何使用action
字段里的链接。
那我们能不能直接让 server 返回下一个状态的 HTML 结构呢?这就是 HATEOAS 的理念。每次应用程序状态的变化,不是靠数据驱动,而是页面结构和元素(超媒体)直接驱动。比如上面的例子可能得到类似这样的响应结果:
这个响应结果可以直接嵌入当前 HTML 页面的某个位置,让应用程序进入下一个状态,即直接通过超媒体驱动,省去了大量 JavaScript 的操作。
开始上手
这里有个官方提供的例子,可以直观感受一下用法:
Htmx 更符合声明式的编程语法,有点所见即所得的意思。如上面的声明告诉 Htmx:
当用户
单击
按钮,向/click
的路由发送POST
请求,并把返回的内容设置到#parent-div
表示的容器中。
看起来这种用法的确可以减少前端开发量,代码简单明确,也确实有商业项目从 React 迁移到 Htmx 实现的案例。不过我觉得在真正在自己的项目里使用前,至少还应该考虑:
应用规模。上述成功案例只是一个中小规模的应用,对于大型项目,Htmx 能否满足所有业务需求仍需评估。
API 的实现。由于返回结果变为 HTML 格式,那么 API 端可能有更多的渲染工作要做。这方面的技术积累自己是否胜任需要考虑。
重构成本。如果是已有的项目迁移到 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),即开发者应该尽量让一段代码的功能看起来直观(不要让功能定义各处分散)。比如:
以及:
第一段 Htmx 代码直观地看出点击按钮的行为(发起/get
请求),而后一段代码声明按钮控件在一个文件,定义单击事件行为的代码却在另一个文件,就不满足行为局部性约束。
Takeaways
综上,我们可以概括使用 Htmx 开发的要点:
使用声明式的语法(而不是 JavaScript 脚本)来实现前端的交互。
使用超媒体(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
版权声明: 本文为 InfoQ 作者【天择】的原创文章。
原文链接:【http://xie.infoq.cn/article/20376ffad0ad9e54ca09479ba】。文章转载请联系作者。
评论