HTMX 太酷了,我自己写了一个

Lobsters Hottest 工具

摘要

本文探讨了 HTMX 这个库,它偏爱服务器端渲染的 HTML,而非大量使用 JavaScript 的前端。作者发现 HTMX 对于持久化的 UI 组件很有用,但最终出于个人对最小依赖的偏好,决定自己实现一套解决方案。

<p><a href="https://lobste.rs/s/8hiogg/htmx_is_so_cool_i_rolled_my_own">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/06/08 13:18

# HTMX 太酷了,我自己写了一个! 来源:https://dbushell.com/2024/04/16/htmx-and-modern-javascript/ 纯人工创作 - 无AI辅助 2024年4月16日 星期二 [HTMX](https://htmx.org/) 现在很火。它拒绝现代 JavaScript UI,转而使用服务端渲染的 HTML。这并非新概念,而是对旧有思路的进化。它建立在 React 让前端变得臃肿之前我们做事情的方式之上。HTMX 常见的例子包括无限滚动、实时搜索结果等。这些功能我以前肯定用了一百种不同的方式实现。真希望十年前就有 HTMX。 HTMX 并不能解决 React 等试图解决的所有问题。甚至对我来说它显得有些受限。但*在这些限制之内*,HTMX 是金子。我喜欢 **Carson Gross**——HTMX 的作者——在最近的 [PodRocket 播客](https://podrocket.logrocket.com/htmx-v2-carson-gross) 中谈论 HTMX 的方式。他说 HTMX 不是“魔法子弹”,并且: > 我认为 HTMX 背后的一些想法可能比 HTMX 本身更重要。 我也这么认为。 ## 实验 我想给 HTMX 一个公平的尝试。光读文档是不够的。*实际使用*代码才是真正的考验,我找到了一个很好的 HTMX 应用场景。最近我重构了自己托管的[播客 Web 应用](https://git.dbushell.com/dbushell/sauropod)的服务器。之前的版本使用了 [SvelteKit](https://kit.svelte.dev/)。我是 SvelteKit 的粉丝,但对于较小的网站来说,它可能过于复杂。我用自己一直在捣鼓的 [DinoSsr](https://github.com/dbushell/dinossr/) 项目替换了 SvelteKit。我还用它来构建我的[静态站点](https://dbushell.com/2024/02/14/super-fast-builds/)和提供我的[书签博客](https://dbushell.com/2024/01/24/cotton-coder/)。 DinoSsr 主要是服务端。它可以提供前端的“孤岛”组件,但这些组件并不能实现完整的页面交互。这对我的音频播放器组件来说是个问题。当我导航翻页时,它需要保持存在,否则收听体验会立刻中断。让我们看看: sauroPod 截图 sauroPod 截图 左侧的截图展示的是没有标注的 [sauroPod](https://git.dbushell.com/dbushell/sauropod) 设计。中间的截图突出显示了所有 Svelte 组件。SvelteKit 神奇地处理了所有 UI 更新和前端路由。这真的很棒;也许我应该留着它。右侧的截图突出显示了我的新构建。这里只有音频播放器组件有前端 JavaScript。DinoSsr 有意不尝试客户端路由。导航会重新加载整个页面,从而结束任何播放。这并不理想。 我意识到这里有机会使用 HTMX。我有几个页面只在上面截图中我用橙色高亮显示的 `<main>` 区域不同。使用 HTMX,我可以渐进式增强链接,并在不重新加载页面的情况下更新这个区域,从而保持音频组件完好无损。 我尝试了 HTMX,效果很好!然后我立刻移除了 HTMX,并决定自己写一个。但首先: ## 对 HTMX 的一些想法 在我的例子中,HTMX 替代了前端 Svelte。但不是像 React 那样的“即插即用”替代品。这是一种思维上的巨大转变。我觉得这很提神。虽然 HTMX 是以 JavaScript 库的形式提供的,用于渐进式增强前端,但 HTMX 的大部分实现是在后端完成的。HTMX 并没有规定后端的代码。你必须自带服务器模板和配置。提供 HTML 的 HTTP 请求实际上就是 HTMX 的 API。配置 HTTP 头以确保正确的缓存有一些细微差别。这些在[文档](https://htmx.org/docs/#caching)中都有说明,但我认为对于像我这样的 JavaScript 瘾君子来说,服务器相关文档应该更早介绍。 一个小抱怨:我不喜欢使用 `hx-*` 前缀的 HTML 属性,而应该使用 `data-*`(配合 [dataset](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset))。当有标准存在时,为什么还要使用非标准?一个更大的抱怨:HTMX 文档中有很多 `<div>` 示例: ``` <div hx-put="/messages" hx-target="#result"> Put To Messages </div> ``` > 当用户点击这个 div 时,向 URL /messages 发起一个 PUT 请求,并将响应加载到 div 中 我是不是误以为这是 React 教程?用户不应该*点击* `<div>` 元素。在我看来,一些更高级的使用内联 JavaScript 的 HTMX 例子变得有点糟糕。这些例子展示了声明式属性模板的局限性。 撇开批评不谈,我认为 HTMX 提供了一套有限但有用的功能,可以增强许多常见的网页设计模式。如果我讨厌它,就不会花时间写博客了! ## 自己写一个 总之,在成功添加 HTMX 之后,我立刻移除了它!太有趣了,我决定用同样的想法写一个自己的迷你版本。我使用了相同的 `last-modified` 和 `if-modified-since` HTTP 头部以及 `304` 响应来缓存 fetch 请求。我使用了 `pushState`([MDN](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState))和 `popstate`([MDN](https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event))来实现基本的历史集成。我添加了一些代码来提取和替换 `main` 元素。受 [HTMX 预加载扩展](https://htmx.org/extensions/preload/) 的启发,我使用指针事件构建了预加载功能。通过在 `click` 事件触发之前发起 fetch 请求,这带来了一点性能提升。我怀疑在使用我自己的实现过程中,会发现我遗漏的东西。目前它运行良好。 我的实验的[源代码](https://git.dbushell.com/dbushell/sauropod/src/branch/main/static/scripts/sauropod-state.js)在我的 Git 仓库中。它非常基础,但展示了浏览器端实际上需要多少 JavaScript。通过使用 HTMX——或者“我们在家用的 HTMX”——我的代码库变得更小、更简单了。 ## 前端 JavaScript 对于除了最小网站以外的所有网站,模板和“组件”对于组织和复用代码几乎是必要的。这可以在服务端使用 PHP、Ruby、Go、任何语言,甚至 JavaScript 来完成。这需要在浏览器中复制吗?或者更糟,*只在*浏览器中?随着 React 等的流行,我们中许多人都停止问这个问题了。这个项目提醒我,答案是一个响亮的*不*。 前端 JavaScript 疲劳是真实存在的。我自己也犯了过度设计 JS UI 的错,尽管我更喜欢老式的服务端模板。我甚至不认为 HTMX 有那么好,但它背后的哲学让现代 JavaScript 开发者感到尴尬。为此我非常感激。

相似文章

兄弟们,我在搞一个 HTML 流式传输库

Reddit r/AI_Agents

作者正在开发一个 HTML 流式传输库,旨在平滑渲染 HTML 令牌,作为 Markdown 的替代方案,并对表格、SVG 和图表进行了改进。作者希望社区就还需要测试哪些功能提供意见。

构建以HTML为先的网站如何让用户数量一夜翻倍

Lobsters Hottest

一位开发者使用以HTML为先的方法(采用Astro框架)重建了一家公用事业公司的申请表,替换了先前失败的React应用。新网站易于访问,在不良网络连接下也能正常工作,并且在一天之内将用户提交量翻了一番,从而避免了潜在的罚款。

@trq212: https://x.com/trq212/status/2052809885763747935

X AI KOLs Following

该文章认为,与Markdown相比,HTML是AI智能体更优越的输出格式,因为它具有更丰富的信息密度、视觉清晰度、易于分享和双向交互,并分享了作者及Claude Code团队其他成员偏爱HTML的原因。

就他妈用 React

Lobsters Hottest

这篇主观性很强的文章激进地主张在复杂 Web 应用中使用现代 JavaScript 框架(如 React)而非纯 HTML,认为复杂性需要合适的工具。