對 htmx 最常見的批評之一,通常來自第一次聽到它的人,是這樣的:
你抱怨現代前端框架的複雜性,但你的解決方案只是另一個複雜的前端框架。
這是一個絕佳的反駁!這是關於您引入到專案中的任何第三方 (3P) 程式碼都應該提出的正確問題。即使您自己沒有編寫 3P 程式碼,透過將其包含在您的專案中,您也必須理解它——如果您想升級它,則必須更新這種理解。這是一個很大的承諾。
讓我們將這種批評分解為其組成部分,並確定 htmx 在多大程度上放縱了它聲稱要解決的危害。
一些 htmx 的支持者跳出來幫助我們說:「htmx 不是框架,它是一個函式庫。」這可能是不正確的。
「框架」是一個口語詞彙——對於某些第三方程式碼從「函式庫」演變為「框架」的確切時間點,沒有硬性規定——但我們仍然應該嘗試定義它。在這個脈絡下:
如果您喜歡隱喻:函式庫是您添加到機器中的齒輪,框架是一個預先構建好的機器,您可以透過自訂其齒輪來控制它。
這種區別,儘管可能模糊不清,但很重要,因為它描述了某些第三方程式碼可以被取代的容易程度。例如,使用 CSV 解析函式庫的 JavaScript 服務可能可以輕鬆地換入不同的 CSV 解析函式庫;然而,使用 NextJS 框架的 JavaScript 服務很可能在其整個生命週期中都依賴 NextJS,因為程式碼的絕大部分是在假設它與 NextJS 建構互動的情況下編寫的。
因此,如果您的服務建立在框架之上,其使用壽命將與該框架的使用壽命綁定。如果該框架被放棄、被鄙視或是不適合使用,修改專案的難度將穩步增加,直到您放棄修改它,並最終將其擱置。
當人們問「htmx 只是另一個 JavaScript 框架嗎?」時,他們擔心的是這個。他們想確保自己不會承諾使用一個很快就會過時的系統,就像過去的許多 Web 開發框架一樣。
所以:htmx 是一個框架嗎?它是否會很快過時,在其迅速衰落之後留下一連串無法維護的網站?
對於我們社群關於這個問題的持續辯論,我在此致歉——我認為 htmx 很明顯是一個框架,至少在大多數的使用案例中是如此。但這取決於您如何使用它。
無論您在專案的何處使用 htmx,您都會在 HTML 中包含 htmx 屬性(例如 hx-post
、hx-target
),編寫使用 htmx 格式化資料(帶有特定請求標頭)呼叫的端點,並從這些端點傳回 htmx 期望格式的資料(帶有 hx-*
控制項的 HTML)。所有這些屬性、標頭和端點會彼此互動,建立一個元素透過網路請求進入和退出 DOM 的系統。
如果您使用 htmx 來處理網站的許多網路請求,那麼在應用程式中包含 htmx 對於專案的結構具有重大影響,從您建構前端標記的方式到端點進行的資料庫查詢。這是一種類似框架的行為,在這種情況下,htmx 不能輕易被取代。
您絕對可以像使用函式庫一樣使用 htmx,僅為網頁的幾個部分新增動態功能。但是您也可以以這種函式庫的方式編寫 React,但沒有人認為 React 不是框架。可以這麼說,許多在應用程式中使用 htmx 的人都是以屈從於 htmx 的方式使用它,將其作為建構超媒體應用程式的框架。
他們應該這麼做!如果您發揮 htmx 的優勢,使用 htmx 建構會好很多。如果您真的堅持,您可以發送 JSON 格式的表單主體,如果您真的堅持。但是您不應該這樣做!使用 application/x-www-form-urlencoded
主體並編寫一個接受它們的端點會更簡單。您可以編寫一個在多個不同用戶端之間重複使用的端點,如果您真的堅持。但是您不應該這樣做!將您的資料和超媒體 API 分成單獨的 URL 會更簡單。是的,htmx 可以作為函式庫使用,但也許也讓它成為您的框架吧。
然而,這並不表示 htmx 只是另一個 JavaScript 框架,因為 htmx 具有其他框架不具備的巨大優勢:HTML。
假設您將 htmx 作為框架使用——它是一個 JavaScript 框架嗎?從一個顯而易見的意義上來說,是的:htmx 是用約 4k 行 JS 實作的。但在另一個更重要的意義上,它不是:React、Svelte、Solid 等等都要求您編寫框架會轉換為 HTML 的 JS(X);而 htmx 只是讓您編寫 HTML。這消除了可能會導致您隨著時間推移而放棄其他框架的整個類別的維護工作。
當您想要升級或變更某些相依性時,程式碼庫往往會陷入困境,但您使用的框架與該變更不相容。Java 是這裡最惡名昭彰的罪魁禍首——有無數百萬行的 Java 程式碼在生產環境中永遠不會離開 Java 8,因為升級 Spring 太難了——但 npm 套件生態系統緊隨其後。當您使用 htmx「框架」時,您永遠不會遇到這個問題,因為 htmx 是一個零相依性、用戶端載入的 JavaScript 檔案,因此保證永遠不會與您的伺服器依賴的任何建置過程或相依性鏈衝突。
瀏覽器會呈現 HTML,因此永遠不需要編譯器或轉譯器來使用 htmx。雖然許多 htmx 使用者很樂意使用 JSX 呈現 API 回應,但 htmx 可以很好地與經典樣板引擎搭配使用,使其可移植到您喜歡的任何語言。說說你對 Django 和 Rails 的看法,但它們在 2008 年是相關的,今天仍然相關——htmx 可以與它們無縫整合。這是 htmx 驅動開發的一個反覆出現的主題:htmx 可以很好地與新舊開發工具搭配使用,因為所有這些工具的共通點都是 HTML,而 htmx 用於編寫 HTML。
推動使用者主要在 HTML 而不是 JS 中定義應用程式的行為具有太多優點,無法在本篇文章中全部涵蓋,因此我將堅持人們最討厭 JavaScript 框架的一點:變化。根據您編寫 React 應用程式的時間,您可能使用受控類別元件、react hooks或此實驗性 <form>
擴充功能編寫表單。這真的很令人抓狂,特別是如果您像我一樣,第一次學習如何使用類別元件建立 Web 表單。
然而,無論您何時編寫 htmx 應用程式,htmx 表單的行為始終以與一般 HTML 表單大致相同的方式定義:使用 <form>
。使用 htmx 新增額外的網路功能,您終於可以使用 PUT
請求並控制回應的去向,但在所有其他方面(驗證、輸入、標籤、自動完成)都具有預設的 <form>
元素行為。
最後,由於 htmx 只是在非常狹窄的領域(網路請求和 DOM 替換)中擴充了 HTML,因此您編寫的大部分「htmx」只是普通的舊 HTML。當您可以存取複雜的狀態管理機制時,實作自訂可折疊 div 非常容易;當您沒有時,您可能會停下來搜尋一下 <details>
元素。只要問題可以透過原生 HTML 元素解決,程式碼的壽命就會大大提高。這是一種學習 Web 開發的更不疏離的方式,因為只要 HTML 存在,您的大部分知識都會保持相關性。
在這方面,htmx 更像是 JQuery 而不是 React(htmx 的前身 intercooler.js 是 JQuery 的擴充功能),但它透過使用宣告式的、基於 HTML 的介面改進了 JQuery:JQuery 要求您進入 <script>
標籤來指定 AJAX 行為,而 htmx 只需要一個簡單的 hx-post
屬性。
簡而言之,雖然 htmx 可以作為框架使用,但它是一個偏離 Web 語意遠小於 JavaScript 框架的框架,並且由於 Web 的絕佳的向後相容性保證,將在不需使用者額外工作的情況下受益於這些語意的改進。如果您想建立一個可以使用很長時間的網站,這些品質使 htmx 比許多同類產品都更好。
注意:儘管同意此分析,在本篇文章中沒有發現任何邏輯缺陷,並允許我在他的網站上發布它,Carson 仍然堅持認為 htmx 是一個函式庫。