你以为升级 HTMX 只是换个版本号?今天这件事被四个 breaking change 彻底扒干净了
写过 HTMX 项目的人都踩过这个坑——收到 major 版本更新通知,兴冲冲把 CDN 换成新版,结果页面直接报一堆事件监听失效、属性不继承、错误响应不显示了。以前只能自己一行行对 changelog。今天 HTMX 4.0 官方出了个 upgrade-check CLI,把这件事彻底透明了。
HTMX 4.0 的四个核心 Breaking Change:
1. 属性继承从隐式变显式
v2 里父元素的 hx-target 会自动传给子元素,v4 必须加 :inherited 后缀才生效:
<!-- v2:自动继承 target -->
<div hx-target="#output">
<button hx-post="/up">赞</button>
</div>
<!-- v4:必须显式声明 -->
<div hx-target:inherited="#output">
<button hx-post="/up">赞</button>
</div>
不加 :inherited 的子元素不会继承任何属性。想恢复 v2 行为?设 htmx.config.implicitInheritance = true。
2. 4xx/5xx 响应默认会 swap 进 DOM
v2 里服务端返回一个 400 错误,HTMX 静默忽略,页面毫无反应;v4 默认会把错误响应当正常内容 swap 进来:
// 恢复 v2 行为
htmx.config.noSwap = ['4xx', '5xx'];
3. 历史导航不再用 localStorage 快照
v2 里点浏览器后退键,HTMX 从 localStorage 恢复 DOM 快照;v4 默认重新发请求拿页面。好处是再也不怕第三方库偷偷改 DOM 导致快照出问题:
// 想恢复快照?装官方扩展 hx-history-cache
4. 60 秒默认超时 + hx-delete 不再带表单数据
v4 里 hx-delete 默认不携带所在表单的数据了,v2 是会带的。如果你在 form 里用 delete 按钮,需要显式加 hx-include="closest form"。
事件名也全面改成 htmx:phase:action 格式,htmx:beforeRequest → htmx:before:request,htmx:afterSwap → htmx:after:swap。
官方 upgrade-check CLI 怎么用:
# 装完直接跑,扫描你的项目
npx htmx.org@4.0.0 upgrade-check -- ./src
# 支持 .vue / .php / .erb 等多种文件后缀
npx htmx.org@4.0.0 upgrade-check --ext .vue ./src
输出格式是 文件名:行号,点开直接跳进去修。工具会检测:隐式继承属性、旧事件名写法、hx-disabled-elt vs hx-disable 变化、hx-ext 移除等。
渐进迁移方案:
不想一次性改完?装 htmx-2-compat 扩展,把 v4 的新事件名、旧继承行为、错误响应逻辑全部桥接回来,代码可以一点点改,改完的组件直接生效,没改的继续走兼容层:
<script src="htmx.org@4.0.0"></script>
<script src="extensions/htmx-2-compat.js"></script>
现在该不该升?
npm 的 latest 标签 2027 年前都指向 2.x,HTMX 团队承诺无限期维护旧版。如果你项目用 CDN 没锁版本,大概率还在跑 2.x。如果你在用 Vite/Webpack 打包,直接上 4.0 不锁版本,upgrade-check 跑一遍,该修的修完,收益是 fetch 重写带来的流式响应、SSE/WebSocket 原生支持这些新能力。
下一步:
跑一遍 npx htmx.org@4.0.0 upgrade-check -- ./src,看看有多少文件需要改。四个 breaking change 里有几个真正影响你项目的,再决定是否现在就升还是等社区踩完坑再动。
评论区
登录后可评论。