[Web翻譯]我們如何在 GitHub 使用 Web 元件

Sunbreak發表於2021-05-17

原文地址:github.blog/2021-05-04-…

原文作者:github.blog/author/kodd…

釋出時間:2021年5月4日

在GitHub,我們為能提供一流的開發者體驗而自豪。我們有相當一部分工作是在我們的前端,我們努力保持儘可能的輕量級、快速和可訪問。對於像GitHub這樣大的產品,這可能是一項相當艱鉅的任務。像許多前端程式碼庫一樣,我們利用元件、獨立、隔離和可重用的程式碼片斷,使應用團隊能夠快速有效地提供高保真的使用者介面,同時仍然保持我們的高標準質量。

在GitHub,我們正在大力使用Web元件。我們有十幾個開源的Web元件,還有幾十個是閉源的。

我們是如何做到這一點的

當GitHub在十年前推出時,我們有一個規模不大的前端程式碼庫,主要使用jQuery。十年後,我們有了一個龐大的前端程式碼庫,開始出現成長的煩惱。我們最終放棄了jQuery(原因我們在當時的一篇博文中做了詳細說明),開始使用新的技術來更好地解決我們的問題。

我們開始涉足一種叫做Web Components的新技術,這是一套原生的瀏覽器技術,允許開發定製的HTML元素,並用JavaScript逐步增強。

我們選擇使用Web Components是因為我們的程式碼庫已經被結構化為類似元件的行為。然而,隨著GitHub單體規模的擴大,我們發現有必要在前端變得難以管理之前實現更好的封裝--而Web Components正符合這一要求。Web元件比我們現有的JavaScript行為提供了更好的可移植性和封裝性。我們很高興在我們現有的前端基礎設施的基礎上嘗試使用Web元件,因為它不會產生任何前期成本或 "買進 "一個特定的框架。

我們的第一批兩個自定義元素在2014年發貨。<relative-time><local-time>,它們以友好的格式顯示時間和日期,以及<include-fragment>,它允許我們延遲載入HTML片段。慢慢地,我們意識到這些元素有多麼強大,並開始在程式碼庫中全盤替換設計模式,例如用<details-dialog>替換我們的 "facebox "模態對話方塊模式。我們的元件現在從非常通用的、多用途的行為(如<remote-input>)到特定的單一用途的元件(如<markdown-toolbar>元素和它的兄弟姐妹)。

對於Web Components所提供的功能,仍有一些痛點和隱患。面對由幾十個團隊的數百名工程師所擁有的如此龐大的程式碼庫,我們需要提供儘可能多的支援和工具,在不使手工程式碼審查成為瓶頸的情況下對最佳實踐進行編碼。

改進我們編寫元件的方式

為了讓工程師有效地編寫高質量的Web元件,並鼓勵最佳實踐,我們一直在開發一些工具,使編寫Web元件變得更加容易。

ViewComponent

我們一直在將我們的Rails程式碼過渡到使用ViewComponent,這是一個用於在Rails中構建可重用元件的框架。ViewComponent與Web Components相輔相成,因為ViewComponent可以與Web Component有一對一的關係,使我們的開發者可以在前端和後端使用單一的抽象概念。

催化劑

Catalyst是我們的開源庫,它使編寫Web元件變得更容易,它一直是將我們的一些最佳實踐聯絡在一起的驅動力。Catalyst利用TypeScript來新增裝飾器,這節省了很多編寫Web元件所需的模板。

Catalyst從優秀的Stimulus庫和Google的LitElement中獲得靈感。它的設計是為了滿足我們的開發者的特定需求。我們內部的開發者經驗調查顯示,在編寫程式碼方面比傳統模式有了很大的改進。

你可以在我們的指南中閱讀更多關於催化劑和它的慣例、模式和反模式的內容。

工具

我們為開發者提供了一套開源的linter配置。對於一般的程式碼實踐,我們有eslint-plugin-github。我們還有eslint-plugin-custom-elements,它為編寫Web元件提供了進一步的檢查。將這些提取到開放原始碼倉庫,使我們能夠從單體中刪除程式碼,但保持一致。

我們也有內部測試來驗證開發人員是否遵循了最佳實踐,並確保他們不會繼續使用已廢棄的模式和行為。我們的一個測試確保一個被廢棄的 "臉譜 "模式不會被引入程式碼庫,並建議使用<details-dialog>元素作為替代。

class FaceboxDeprecationTest < Test::Fast::TestCase
  EXPECTED_NUMBER_OF_FACEBOXES = 44

  # Find facebox triggers set with rel=facebox, in either HTML attributes or
  # as part of hash assignment (for rails helpers)
  REGEX_FOR_FACEBOX_BINDING = %r|rel\s*[=:]>?\s*["']?facebox|
  REGEX_FOR_DATA_FACEBOX = %r|data-facebox\s*=>?\s*|

  def test_limit_facebox
    actual_rel_facebox = grep(REGEX_FOR_FACEBOX_BINDING, options: %w[-In], paths: %w[app/**/*.erb])
    actual_data_facebox = grep(REGEX_FOR_DATA_FACEBOX, options: %w[-In], paths: %w[app/**/*.erb])
    count = actual_rel_facebox.count("\n") + actual_data_facebox.count("\n")

    assert_operator count, :<=, EXPECTED_NUMBER_OF_FACEBOXES, <<-EOL
It looks like you added a facebox. Please use <details-dialog> instead.

If you must increment EXPECTED_NUMBER_OF_FACEBOXES in this test, please
/cc @github/ui-frameworks-reviewers in your pull request, as we may be able to help! Thanks.
EOL

    assert_equal EXPECTED_NUMBER_OF_FACEBOXES, count, <<-EOL
It looks like you removed a facebox. YOU ARE AWESOME! ? ? ? ? ?
Please decrement EXPECTED_NUMBER_OF_FACEBOXES in this test and treat yourself to
something special.  You deserve it.
EOL
  end
end
複製程式碼

我們的網路元件的新生命週期

從一個特定的應用程式的前端行為到一個開源的Web元件的道路始於微控制器程式碼庫中的催化劑元件。那些適合提取的元件會被概括成一個強大的、嚴格的行為、無依賴性的Web元件。

在單體中,工程師們可能會對想法進行原型化,並在不斷修改的同時使用功能標誌慢慢地將其交付。在元件經過一段時間的生產測試後,我們會尋找機會將元件提升到自己的倉庫中。我們也會定期評估程式碼庫,以找到可重用的模式、通用的行為,或者那些有令人信服的理由被提升到自己的倉庫的元件。

從催化劑開始

我們鼓勵開發者在dotcom monolith內開發使用者介面時編寫Catalyst元件。從一開始就使用Catalyst的好處是,這個庫可以抽象出一些編寫Web元件的常見陷阱,並強制執行最佳實踐。

註冊一個Web元件可能會產生一些模板,但我們通過命名慣例和灑上TypeScript裝飾器使其變得簡單。催化劑中的動作使事件監聽比管理全域性事件監聽器更容易。突變現有HTML的目標比在瀏覽器中渲染HTML模板更好。

從單體中提取一個元件

當元件包含在我們的應用程式中時,當它們在不同的環境中被使用時,可能會有特定的應用程式程式碼被新增到它們中。當你有特定的需求需要滿足時,應用特定的程式碼是可以的,但如果一個元件要在其他情況下工作,它就需要靈活和通用。大多數情況下,這是以硬編碼選項的形式出現的,應該使其可配置。歸納出一個元件,使其更具有可移植性,這對其他團隊的重複使用至關重要。

在提取催化劑元件之前,我們刪除了催化劑的特定功能,並將其轉換為普通的網路元件。為什麼要刪除團隊聲稱能使編寫Web元件更容易的庫?雖然Catalyst對開發者有好處,但我們希望我們的元件是零依賴性的。要求GitHub組織以外的開發者在為元件貢獻程式碼之前瞭解Catalyst,是我們不希望發生的額外摩擦。

開源元件意味著特殊要求

雖然微控制器元件可能與特定的應用邏輯緊密耦合,有第三方的依賴性,並依靠現有的測試,但我們對開源元件有一套不同的標準。我們的開源元件應該有接近0的依賴性,與框架和庫無關,輕量級,無風格,與任何其他元件解耦,並且應該只做一件事,而且是一件好事。

雖然我們希望我們的元件是無依賴性的,但我們也希望從單體中獲得同樣的健壯性保證,這包括型別。我們將TypeScript定義與我們的元件一起,也使用ES模組編寫,以使捆綁器能夠輕鬆消費它。我們還確保有一個完整的測試套件和linter設定,使用我們的標準化配置。

<typing-effect>元素就是一個經歷了開源生命週期的元件的優秀例子。GitHub內部的一個產品工程團隊最近製作了一個靈感來自終端的使用者介面原型,其中的文字看起來就像有人在打字一樣。在之前的一個專案中,我們使用了優秀而強大的typed.js來製作打字動畫,因此該團隊最初再次使用了這個庫。

該團隊已經建立的UI部分是輕量級的,而我們的工具識別出在頁面上新增typed.js將使捆綁的大小增加五倍。UI系統團隊要求產品工程團隊考慮其他選擇。我們發現,我們對這個應用程式所需要的功能是有限的,因此值得嘗試自己建立它。

產品工程團隊為新的使用者介面編寫了我們自己的打字動畫的第一個版本。使用Catalyst,它花了不到一天的時間和不到40行的程式碼。意識到其他團隊可以使用這種效果,我們決定把它放到生命週期的步驟中。我們重構了這個元件,使其沒有依賴性,將其從Catalyst庫中 "彈出",並將該元件作為<typing-effect>開源。

結果

總的來說,我們對自上一篇文章以來對GitHub前端所做的改變感到非常興奮。根據我們進行的內部開發者調查,我們的開發者對Catalyst和ViewComponent非常滿意

開發者喜歡ViewComponent的封裝,使其更容易測試UI並增加開發者的信心。開發人員認為Catalyst是一種從 "舊式 "JavaScript中獲得的可喜變化,而不需要大規模地跳躍到一個不同的框架或正規化。

下一步是什麼?

我們正在繼續以 "GitHub元素 "的名義開放更多的通用開源行為網路元件。我們在 github.com/github/gith… 上有這些元素的集合,它與我們在 webcomponents.org 上的頁面同步。

我們對Web Components的未來感到興奮,並繼續關注對HTML規範的修改建議。最近,我們最興奮的兩項提議是模板部件宣告式陰影DOM提議。這些建議將使工程師們更容易釋出Web元件,並將解決我們對Web元件當前狀態的一些共同痛點。我們已經在一個ponyfill中實現了模板部件的最小可行部分,目前正在生產中使用,我們非常希望看到它在更廣泛的社群中得到推廣。

特別感謝

感謝Keith Cirkel啟動這篇文章,感謝Ben Scofield和Joel Hawksley審查這篇文章,感謝Nick Holden與我們合作,提取<typing-effect>元素。


通過www.DeepL.com/Translator(免費版)翻譯

相關文章