如何結合使用HTML與Htmx并減少JavaScript代碼量
譯文譯者 | 李睿
審校 | 孫淑娟
HTML作為宇宙的中心
眾所周知,全球互聯網得以蓬勃發展在很大程度上歸功于HTML和CSS。Javascript(JS)可以充當HTML和CSS之間的粘合劑,使頁面更具動態性和交互性,但Web編程的歷史發展不同。在客戶端渲染和其他類似技術出現之后,使用JS創建Web應用程序變得更加困難。
什么是Htmx?
Htmx是一個庫,允許用戶使用簡單的標記創建現代且強大的用戶界面。多虧有了它,可以直接從HTML元素執行AJAX請求、觸發CSS轉換、調用WebSocket和服務器發送的事件。
SSR應用
Htmx的使用促使人們逐漸放棄客戶端渲染(CSR),轉而支持服務器端渲染(SSR)。服務端渲染(SSR)被認為是最后的手段,只有在需要快速提高性能時才使用。但是,服務端渲染(SSR)可以構建應用程序的整個用戶界面。
Htmx不需要任何其他JS包即可運行,并且與框架和語言無關。因此,它可以與任何服務器平臺一起使用,例如NodeExpress、RAILS、Django、Phoenix、Laravel等。
重用服務器上的組件
Htmx允許用戶使用更熟悉的庫重用服務器端用戶界面(UI)元素;例如,用于Node的Pug或用于RAILS和Django的模板庫。它有助于使HTML變得復雜和動態。
這里是RentalsListing,一個使用Express.js和HTML構建的演示應用程序。它對統計和動態場景使用相同的部分:
HTML
ul.results
each rental in rentals
li
article.rental
button.image(type="button", _="on click toggle .large then if #view-caption.textContent === 'View Larger' then set #view-caption.textContent to 'View Smaller' else set #view-caption.textContent to 'View Larger'")
img(src=rental.attributes.image, alt='An image of ' + rental.attributes.title)
small#view-caption View Larger
.details
h3
a(href='/rentals/' + rental.id) #{rental.attributes.title}
.detail.owner
span Owner:
| #{rental.attributes.owner}
.detail.type
span Type:
| #{rental.attributes.category}
.detail.location
span Location:
| #{rental.attributes.city}
.detail.bedrooms
span Bedrooms:
| #{rental.attributes.bedrooms}
.map
img(alt='A map of ' + rental.attributes.title, src=rental.mapbox, width="150",height="150")
在主頁的列表中,使用了Pug庫中的include來顯示部分內容:
HTML
extends layout
block content
.jumbo
.right
h2 Welcome to Super Rentals!
p We hope you find exactly what you're looking for in a place to stay.
a.button(href="/about") About Us
.rentals
label
span Where would you like to stay?
input.light(type="text", name="search",
hx-post="/search" ,
hx-trigger="keyup changed delay:500ms" ,
hx-target=".results" ,
hx-indicator=".htmx-indicator")
include includes/rental-list.pug
每次用戶在網站上搜索租賃房產時,都可以使用相同的部分填充搜索結果。結果如下所示:
JavaScript
app.post('/search', (req, res) => {
const { search } = req.body;
const results = _rentals.data.filter(r => {
const _search = search.toLowerCase();
const _title = r.attributes.title.toLowerCase();
return _title.includes(_search);
});
const template = pug.compileFile('views/includes/rental-list.pug');
const markup = template({ rentals: results });
res.send(markup);
});
服務器端路由
客戶端路由帶來了一系列問題。例如,在基于散列的路由和基于URL的路由之間總是存在一個兩難選擇。由于舊版瀏覽器(如Internet Explorer 11)不支持歷史API,因此在URL中使用片段ID的基于哈希的路由幾乎總是首選。
大多數JS框架都實現了自己的客戶端路由邏輯。同時,所有框架都使用自己的瀏覽器API,例如window.history。這導致應用程序中出現大量樣板代碼。
更少的JS代碼
Htmx的主要優勢在于編寫并發送到瀏覽器的JS代碼量。與hyperscript一起,該庫允許用戶創建豐富的交互式應用程序,而無需使用JS中的客戶端代碼:
HTML
<!-- have a button POST a click via AJAX -->
<button hx-post="/clicked" hx-swap="outerHTML">
Click Me
</button>
當單頁應用剛開始流行時,社區采用JSON作為數據交換的標準。現在,為了從JSON數據中對HTML進行逆向工程,用戶通常需要處理通過API來自服務器的大量客戶端數據。API響應通常包含不完整或冗余的數據。
為了解決這個問題,已經開發了像GraphQL這樣的復雜替代方案,因此用戶只能從服務器獲取所需的數據。Htmx提供了更好的解決方案:只需將HTML替換為從服務器接收到的HTML響應,而不再需要客戶端數據。
不再構建/編譯
Htmx的另一個優點是不再采用Web應用程序構建工具。可以改用CDN工具:
HTML
<!-- Load from unpkg -->
<script src="<https://unpkg.com/htmx.org@1.3.3>"></script>
不再構建是Web應用程序開發的全球趨勢。一方面,ES模塊規范已經被所有瀏覽器開發者所接受。另一方面,現在有了Skypack、Snowpack和Vite工具,可以與CDN和ESM方法結合使用。所有這些最終將導致客戶端JavaScript的構建減少。此外,無需安裝數千個npm包并維護復雜的構建配置。
統一代碼庫
一個應用程序的兩個代碼庫意味著額外的開發挑戰。特別是,需要同步更新部署、兩次配置構建管道、更新兩個庫中的框架、維護代碼,并從兩個源運行測試包。
Htmx允許用戶將所有代碼組合在一個地方:由于渲染在服務器端進行,因此不需要單獨的接口基礎。從長遠來看,這可以為用戶節省大量時間和費用。此外,開發人員可以更加一致地采取行動,他們不必檢查兩個或更多存儲庫。
行為原則的局部性(LoB)
LoB原理是由編程理論家Richard Gabriel提出的。他指出,所有開發人員都應該努力確保每段代碼的行為在驗證時是顯而易見的。
Gabriel認為,局部性對于保持代碼易于維護至關重要。局部性是一種特性,它允許程序員在看到代碼的一小部分后就可以了解代碼屬于架構的哪一部分。
它看起來像這樣:
HTML
The behaviour of a code unit should be as obvious as possible by looking only at that unit of code
<div hx-get="/clicked">Click Me</div>
缺乏狀態同步的問題
客戶端狀態管理產生的問題比解決的問題多。這一原則的實現導致客戶端和服務器端都需要狀態管理。另一種解決方案是將狀態存儲在服務器上。在這種情況下,客戶端充當虛擬執行器,用于呈現狀態更改。
這與瘦客戶機模式類似,瘦客戶機模式是一種帶有連接到終端服務器的輕量級操作系統。這些設備被用來創建第一個用于節省資源的Web應用程序。
Htmx將幫助用戶避免混淆狀態管理網絡中的用戶界面(UI)代碼;例如,雙向數據綁定、單向數據流和反應式數據。
原文標題:??Removing JavaScript: How To Use HTML With Htmx and Reduce the Amount of Code??,作者:Alexey Shepelev