在最近的前端开发技术的探讨中,htmx经常成为热议的话题。一些人批评它,认为尽管htmx批评现代前端框架过于复杂,但它自己却似乎也是一个复杂的框架。这种看法值得我们深入思考。因为当你将任何第三方代码引入你的项目时,无论是htmx还是其他,都意味着你需要理解并维护它,尤其是在升级的时候。所以,让我们仔细分析一下这种批评,并探究htmx在解决它所宣称的问题时的实际表现。
库与框架:有何不同?
关于htmx是库还是框架的讨论,常常出现在争论之中。有人辩称htmx实际上是一个库,而不是框架。但这种说法可能不太准确。
“框架”这个词在技术上并没有一个严格的定义,它和“库”之间的界限并不是那么明显。但我们还是可以尝试去区分它们:
- 库(Library):这是一种API对应用程序其他部分影响不大的第三方代码。
- 框架(Framework):这种代码的API则决定了应用程序的整体结构。
这个比喻可能会更加形象:库就像是你添加到机器中的齿轮,而框架则像是一个你通过定制齿轮来控制的预制机器。
这种区别之所以重要,是因为它关系到代码的可替换性。比如,一个使用了CSV解析库的JavaScript服务可以相对容易地更换另一个CSV解析库;但如果是使用了NextJS这样的框架,服务可能就会在整个生命周期中依赖于NextJS,因为大量代码都是基于与NextJS构件的交互编写的。
因此,如果你的服务是基于某个框架构建的,它的有效寿命就与该框架的有效寿命紧密相连。如果那个框架被废弃、不受欢迎或难以维护,那么修改你的项目就会变得越来越困难,直到最后你不得不放弃对它的修改,并可能整个项目被搁置。
这正是人们在问“htmx只是另一个JavaScript框架吗?”时的担忧所在。他们不希望自己投入到一个很快就会过时的系统中,就像过去很多Web开发框架那样。
htmx:框架还是更多?
尽管社区对此存在争议,但从我个人的角度看,htmx在大多数使用场景中显然更接近于一个框架。当然,这也取决于你如何使用它。
当你在项目中使用htmx时,你会在HTML中包含htmx的属性(比如hx-post,hx-target),编写以htmx格式化数据(带有特定请求头)来调用的端点,并从这些端点返回htmx期望的格式化数据(带有hx-*控制的HTML)。所有这些属性、头部和端点的相互作用,创建了一个通过网络请求使元素进入和退出DOM的系统。
如果你在网站的许多网络请求中使用htmx,那么引入htmx对项目结构的影响是显著的,从如何构建前端标记到端点进行的数据库查询,htmx的加入都会对整个应用程序架构产生深远影响。这种影响是框架式的,意味着一旦采用了htmx,就不容易被替换掉。
当然,你也可以选择以更类似于库的方式使用htmx,仅在网页的某些部分添加动态功能。这就像你可以用类似库的方式使用React,但这并不意味着React不是一个框架。实际上,很多开发者在他们的应用中使用htmx,都是在遵循htmx的框架式要求,将其作为构建超媒体应用的一个框架。
使用htmx最有效的方式是顺应它的优势。例如,你当然可以选择发送JSON格式化的表单体,但更简单的做法是使用
application/x-www-form-urlencoded格式,并编写一个能接受这种格式的端点。同样地,你也可以编写一个跨多个不同客户端重用的端点,但更简单的做法是将你的数据和超媒体API分离到不同的URL。是的,htmx可以作为库使用,但让它成为你的框架可能会更好。
htmx的独特优势:HTML
尽管htmx在很多情况下被当作一个框架使用,但这并不意味着它就是“另一个JavaScript框架”。htmx最大的优势在于它的核心是HTML。
如果你将htmx当作框架来使用,那么从一个角度来看,它确实是基于大约4000行JS实现的。但从另一个更重要的角度来看,htmx并不是:不像React、Svelte、Solid等让你编写JS(X)并将其转换为HTML的框架,htmx让你直接编写HTML。这种方式避免了很多其他框架随着时间推移可能带来的维护问题。
例如,当你想升级或更改某些依赖时,如果你使用的框架与这种更改不兼容,代码库往往会遇到困难。Java是一个著名的例子——有无数行Java代码因为升级Spring太难而永远停留在Java 8。但当你使用htmx时,你不会遇到这个问题,因为htmx是一个零依赖的、客户端加载的JavaScript文件,它不会与你的服务器依赖的任何构建过程或依赖链发生冲突。
另一个重要优势是,浏览器直接渲染HTML,因此使用htmx时不需要任何编译器或转译器。虽然许多htmx用户喜欢用JSX来渲染API响应,但htmx与传统的模板引擎兼容性良好,可以轻松移植到任何语言。Django和Rails在2008年就很流行,到今天仍然如此——htmx也可以与它们无缝集成。htmx的一个反复出现的主题是,它与新旧开发工具都很好地搭配,因为这些工具的共同点是HTML,而htmx正是用来编写HTML的。
将用户的主要工作聚焦在HTML上,而不是JS上,带来了许多优势。这种方式简化了学习过程,使得开发者不必为了追随JavaScript框架的最新趋势而疲于奔命。无论何时
编写你的htmx应用程序,htmx表单的行为始终与普通HTML表单的定义方式大致相同:使用<form>标签。通过htmx添加的网络功能,例如使用PUT请求并控制响应的去向,都是对传统HTML表单的增强,但在验证、输入、标签、自动完成等方面,你依然享受到标准<form>元素的默认行为。
更重要的是,因为htmx仅在网络请求和DOM替换这一狭窄领域扩展了HTML,所以你编写的大多数“htmx”代码实际上就是普通的HTML。这意味着当你遇到可以通过原生HTML元素解决的问题时,你的代码将更加长青。例如,当你需要一个可折叠的div时,如果没有复杂的状态管理机制,你可能会选择使用<details>元素,而不是编写复杂的JavaScript。这种方式使得学习Web开发变得更加友好,因为你的大部分知识将随着HTML的持续有效而保持相关性。
从这个角度来看,htmx更像是JQuery而不是React(实际上,htmx的前身intercooler.js是一个JQuery扩展)。但它在JQuery的基础上做了改进,采用了声明式、基于HTML的接口:JQuery要求你在<script>标签中指定AJAX行为,而htmx只需要一个简单的hx-post属性。
总的来说,虽然htmx可以作为一个框架使用,但它在很多方面都与传统的JavaScript框架不同,它的这些特点使得它更加贴近Web的核心语义——HTML。并且,由于Web的向后兼容性保证,htmx将能够从这些语义的改进中受益,而无需用户进行额外工作。如果你想构建一个持久的网站,这些特性使得htmx成为比许多同代框架更好的选择。
结语
通过这篇对htmx的深入探讨,我们可以看到,htmx在技术上介于库和框架之间,它强调使用HTML来驱动应用的行为,而非依赖复杂的JavaScript结构。这种方法降低了学习曲线,增强了代码的可维护性和可移植性。对于那些寻求简化Web开发流程、减少对复杂JavaScript框架的依赖的开发者来说,htmx提供了一个有趣且有效的选择。
无论htmx被视为库还是框架,其核心价值在于简洁性和对HTML的重视,这使得它在当前的Web开发生态中占有一席之地。这也提醒我们,在追求前沿技术的同时,不应忽视基础技术的力量。在复杂性和现代化的交错中,找到适合自己项目的平衡点,是每个Web开发者的重要任务。