搜尋
首頁後端開發GolangGo-DOM - 重大里程碑

Go-DOM -  major milestone

工作了不到兩週;我終於達到了 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


  1. 如果您成功地聽到了對 BBC 流行廣播劇的致敬,那就太好了。 ↩

  2. 這是基於個人經驗。由於快速的回饋週期,正確執行 TDD 會加快你的速度。真實瀏覽器的開銷往往會讓您在生產程式碼之後編寫測試;失去了快速測試套件為您提供的回饋循環的好處。 ↩

  3. v8go 專案已經奠定了基礎。然而;並非 v8 的所有功能都暴露給 Go 程式碼;包括嵌入本機物件的必要功能。我能夠將它們添加到單獨的叉子中;這仍然是 WIP。 ↩

以上是Go-DOM - 重大里程碑的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Golang vs. Python:利弊Golang vs. Python:利弊Apr 21, 2025 am 12:17 AM

Golangisidealforbuildingscalablesystemsduetoitsefficiencyandconcurrency,whilePythonexcelsinquickscriptinganddataanalysisduetoitssimplicityandvastecosystem.Golang'sdesignencouragesclean,readablecodeanditsgoroutinesenableefficientconcurrentoperations,t

Golang和C:並發與原始速度Golang和C:並發與原始速度Apr 21, 2025 am 12:16 AM

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

為什麼要使用Golang?解釋的好處和優勢為什麼要使用Golang?解釋的好處和優勢Apr 21, 2025 am 12:15 AM

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

Golang vs.C:性能和速度比較Golang vs.C:性能和速度比較Apr 21, 2025 am 12:13 AM

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

golang比C快嗎?探索極限golang比C快嗎?探索極限Apr 20, 2025 am 12:19 AM

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

Golang:從Web服務到系統編程Golang:從Web服務到系統編程Apr 20, 2025 am 12:18 AM

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

Golang vs.C:基準和現實世界的表演Golang vs.C:基準和現實世界的表演Apr 20, 2025 am 12:18 AM

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

Golang vs. Python:比較分析Golang vs. Python:比較分析Apr 20, 2025 am 12:17 AM

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

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

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

熱工具

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

SublimeText3 英文版

SublimeText3 英文版

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

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

mPDF

mPDF

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