工作了不到兩週;我終於達到了 Go-DOM 的第一個重要里程碑。
現在,瀏覽器將在建立 DOM 樹時下載並執行遠端 JavaScript
。簡史
這個專案最初是一個瘋狂的想法;看到 Go 和 HTMX 是一個越來越受歡迎的堆疊;
Go 已經擁有測試純伺服器端渲染所需的所有工具。但是,當添加像 HTMX 這樣的庫時,應用程式的行為是初始 DOM 之間編排的結果;交互元素的屬性;到達的 HTTP 端點以及這些端點傳送的內容;回應標頭和正文。要從使用者的角度驗證行為,您需要一個瀏覽器;或至少是一個行為...與瀏覽器並不完全不同的測試工具。 1
搜尋「Go 中的無頭瀏覽器」只會導致建議在無頭模式下使用真實瀏覽器的結果。這種組合有巨大的開銷;阻礙快速高效的 TDD 循環。依賴真實的瀏覽器通常會減慢您的速度而不是加快您的速度。 2
於是這個想法就被激發了;用純 Go 編寫一個無頭瀏覽器作為 Web 應用程式的測試工具;
首先要解決的不確定性是 HTML 的解析;以及腳本執行。我很快就做到了; 2天內解決這兩個問題。我有一個非常基本的 HTML 解析器;我還將 v8 整合到程式碼庫中3
並使 Go 物件可以被 JavaScript 程式碼存取。HTML 解析器後來被刪除,因為 go x/net/html 已經實作了 HTML 解析器;處理 HTML 解析的所有怪癖。解析格式良好的文件並不是一個非常難解決的問題。它可以優雅地處理格式錯誤的 HTML,但在這方面卻變得棘手。
過了一段時間,我還設法讓內聯
腳本執行在正確的時刻運行;即當元素實際連接到 DOM 時執行腳本,而不是在解析完整的 HTML 之後執行。處理 HTTP 請求
能夠使用內嵌腳本處理 HTML 文件之後;下一步是實際從來源下載
腳本。這就需要整合一個HTTP層;以便瀏覽器自行取得內容;而不是被灌輸內容。http.Client 也允許您使用 http.RoundTripper 介面控制實際的傳輸層。通常你會啟動一個伺服器;它將偵聽 TCP 連接埠上的請求。在這種情況下,TCP 充當傳輸層;但本身與 HTTP 請求的處理無關。由於 Go 中標準 HTTP 堆疊的簡單性;整個 HTTP 伺服器由單一函數 func Handle(http.ResponseWriter, *http.Request) 表示。
無頭瀏覽器可以完全繞過 TCP 堆疊的開銷,並使用自訂的 RoundTripper 直接呼叫此函數。
現在瀏覽器可以執行HTTP請求,但瀏覽器程式碼本身不知道HTTP層被繞過的事實。隨之而來的是在 DOM 解析期間下載腳本的能力。
範例程式碼
讓我們探索一個簡單的測試,就像它現在在程式碼庫中一樣(程式碼使用 Ginkgo 和 Gomega,恕我直言,這是一個有點被忽視的組合)
首先,測試建立一個簡單的 HTTP 處理程序,該處理程序提供兩個端點:/index.html 和 /js/script.js。
It("Should download and execute script from script tags", func() { // Setup a server with test content server := http.NewServeMux() server.HandleFunc( "GET /index.html", func(res http.ResponseWriter, req *http.Request) { res.Write( []byte( `<script src="/js/script.js"></script>Hello, World!`, ), ) }, ) server.HandleFunc( "GET /js/script.js", func(res http.ResponseWriter, req *http.Request) { res.Header().Add("Content-Type", "text/javascript") res.Write([]byte(`var scriptLoaded = true`)) }, ) // ...
此處的目的只是驗證腳本是否已執行。為此,腳本會產生一個可觀察到的副作用:它在全域範圍內設定一個值。
要驗證腳本是否已執行,只需檢查全域範圍,這是透過從測試本身執行臨時 JavaScript 來完成的;驗證表達式的結果。
建立瀏覽器、載入索引檔案並驗證觀察到的副作用的程式碼
browser := ctx.NewBrowserFromHandler(server) Expect(browser.OpenWindow("/index.html")).Error().ToNot(HaveOccurred()) Expect(ctx.RunTestScript("window.scriptLoaded")).To(BeTrue())
測試執行也相當快。測試套件中涉及 JavaScript 執行的部分目前由 32 個測試組成,運行時間為 23 毫秒。
下一個里程碑是整合 HTMX。
由於該專案最初是在嘗試驗證 HTMX 應用程式時構思的,因此合理的下一個目標是支持這種情況。一個簡單的 HTMX 應用程序,帶有一個按鈕和一個計數器,按下按鈕時計數器會增加。
- AnXMLHttpRequest 實作需要就位。為此,工作正在進行中。
- XPathEvaluator。我相信一開始就可以填充。
- 事件傳播。現在僅發出 DOMContentLoaded 和 load 事件。元素需要支援更多的事件;例如點擊;以及觸發它們的方法。
- 這可能還需要正確的事件捕捉和冒泡。
進而 ...
接下來是更進階的使用者互動;正確的表單處理,例如,輸入手線(例如,在 欄位中按enter 提交表單。這通常也涉及某種URL 重定向;這驅動了對歷史物件等的需求.
整合外部站點
具有控制傳輸層的能力;我們可以提供具有獨特能力的測試;我們可以模擬系統在運行時依賴的外部站點。例如,對於給定的主機名,測試可以提供另一個模擬行為的 Go HTTP 處理程序。
最明顯的例子是使用外部身分提供者。此測試可以模擬登入流程的行為;不必強迫您在外部系統中建立虛擬帳戶,由於外部系統中斷而導致測試失敗,或者由於身分提供者引入的 2FA 或驗證碼而根本無法自動化該流程。
另一個用例是使用 API 密集型庫,例如地圖庫,這會產生使用成本。模擬外部站點,以免因執行測試套件而收到額外費用。
可用性勝於相容性
創建 100% 符合 Whatwg 標準的實現是一項艱鉅的任務;直到我真正開始閱讀 Whatwg 規範的部分內容之前,我並沒有完全理解其範圍。目標是創建一個工具幫助為 Web 應用程式編寫測試。完全相容是長期目標;但在專案達到某種程度的可用性之前,我會開始填補漏洞。
因此;在實際應用中更可能使用的功能更有可能被優先考慮。指向給出錯誤結果的實際測試的功能請求可能會被優先考慮。 實施特定標準的功能請求可能會被拒絕。
傳播這個詞
我相信這對許多開發人員來說都是一個非常有用的工具,所以如果您閱讀了本文,請讓您的同事知道它的存在。到目前為止,這只是一個業餘時間項目,目前我有很多空閒時間;但情況不會永遠如此。
如果你想現場觀看,請傳出去......
也許您甚至會贊助這個?您有一家使用 Go 建立 Web 應用程式的大公司嗎?歡迎聯絡我。
在這裡找到項目:https://github.com/stroiman/go-dom
-
如果您成功地聽到了對 BBC 流行廣播劇的致敬,那就太好了。 ↩
-
這是基於個人經驗。由於快速的回饋週期,正確執行 TDD 會加快你的速度。真實瀏覽器的開銷往往會讓您在生產程式碼之後編寫測試;失去了快速測試套件為您提供的回饋循環的好處。 ↩
-
v8go 專案已經奠定了基礎。然而;並非 v8 的所有功能都暴露給 Go 程式碼;包括嵌入本機物件的必要功能。我能夠將它們添加到單獨的叉子中;這仍然是 WIP。 ↩
以上是Go-DOM - 重大里程碑的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Golangisidealforbuildingscalablesystemsduetoitsefficiencyandconcurrency,whilePythonexcelsinquickscriptinganddataanalysisduetoitssimplicityandvastecosystem.Golang'sdesignencouragesclean,readablecodeanditsgoroutinesenableefficientconcurrentoperations,t

Golang在並發性上優於C ,而C 在原始速度上優於Golang。 1)Golang通過goroutine和channel實現高效並發,適合處理大量並發任務。 2)C 通過編譯器優化和標準庫,提供接近硬件的高性能,適合需要極致優化的應用。

選擇Golang的原因包括:1)高並發性能,2)靜態類型系統,3)垃圾回收機制,4)豐富的標準庫和生態系統,這些特性使其成為開發高效、可靠軟件的理想選擇。

Golang適合快速開發和並發場景,C 適用於需要極致性能和低級控制的場景。 1)Golang通過垃圾回收和並發機制提升性能,適合高並發Web服務開發。 2)C 通過手動內存管理和編譯器優化達到極致性能,適用於嵌入式系統開發。

Golang在編譯時間和並發處理上表現更好,而C 在運行速度和內存管理上更具優勢。 1.Golang編譯速度快,適合快速開發。 2.C 運行速度快,適合性能關鍵應用。 3.Golang並發處理簡單高效,適用於並發編程。 4.C 手動內存管理提供更高性能,但增加開發複雜度。

Golang在Web服務和系統編程中的應用主要體現在其簡潔、高效和並發性上。 1)在Web服務中,Golang通過強大的HTTP庫和並發處理能力,支持創建高性能的Web應用和API。 2)在系統編程中,Golang利用接近硬件的特性和對C語言的兼容性,適用於操作系統開發和嵌入式系統。

Golang和C 在性能對比中各有優劣:1.Golang適合高並發和快速開發,但垃圾回收可能影響性能;2.C 提供更高性能和硬件控制,但開發複雜度高。選擇時需綜合考慮項目需求和團隊技能。

Golang适合高性能和并发编程场景,Python适合快速开发和数据处理。1.Golang强调简洁和高效,适用于后端服务和微服务。2.Python以简洁语法和丰富库著称,适用于数据科学和机器学习。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SublimeText3漢化版
中文版,非常好用

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

SublimeText3 Linux新版
SublimeText3 Linux最新版

WebStorm Mac版
好用的JavaScript開發工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),