跳至主要内容
let’s talk about web components

from brad frost

Advanced

/

Other
HTML / CSS
JavaScript / TypeScript

作者想透過這篇文章,介紹 web components 的基本概念、分享他使用 web components 來建立設計系統的經驗和看法,並且解決一些關於 web components 的常見問題和誤解。另外,作者也希望能夠推廣使 web components 成為 web 原生且漸進增強(progressive enhancement)的解決方案。

Web Components

簡單來說,web components 是一套瀏覽器原生的技術,它可以讓我們在 HTML 中定義自己的元素,讓這個元素可以被重複使用。這些 web components 是原生的,也就是說,它們不需要任何的 framework 或是 library,就可以在瀏覽器中運作。所以它們可以被放到任何網站(例如 WordPress, Drupal, Contentful, etc),也可以被放到任何的 web 框架(例如 React, Vue, Angular, Svelte, etc)中。

以下是一個簡單的 web components 的範例。這個 web components 叫做 ds-badge,它可以被重複使用。使用他的開發者只需要透過 web components 的 API 傳入 data 就可以在網頁上顯示出來。

一個叫做 ds-badge 的 web component
<ds-badge variant="success" text="99 Luftballons"></ds-badge>
我們希望 ds-badge 在瀏覽器上顯示出來的東西是:
<div class="badge badge--success">99 Luftballons</div>

不過,web components 需要 JavaScript 才能運作,如果沒有 JavaScript,web components 就無法顯示出來。第一種解決方案是,我們可以在 web components 的 HTML 中,加入一些預設的內容,這樣就可以在沒有 JavaScript 的狀況下,顯示出一些內容。這樣的做法,就是漸進增強(progressive enhancement)的概念。

在 web components 的 HTML 中,加入一些預設的內容
<ds-badge variant="success" text="99 Luftballons">
<div>99 Luftballons</div>
</ds-badge>

Declarative Shadow DOM

Web components 還有一種技術叫做 Declarative Shadow DOM,它可以讓我們在 web components 中,定義一個 shadow DOM。這個技術在 web components 中嵌入一個 <template shadowroot="open">,讓我們在裡面定義這個 web components 還沒有被 JavaScript 處理之前,要顯示出來的 markup 和 styles。直到 JavaScript 成功載入後,真正的 web components 才會被顯示(hydrated)出來。

在 web components 的 HTML 中,加入 Shadow DOM
<ds-badge variant="success" text="99 Luftballons">
<template shadowroot="open">
<style>
.badge {
background-color: green;
color: white;
padding: 0.5rem;
border-radius: 0.25rem;
}
</style>
<div class="badge">99 Luftballons</div>
</template>
</ds-badge>

Current Solution

然而,上述的解決方案及 Shadow DOM 看起來不太美觀,而且漸進增強的轉換方式似乎像是黑魔法,這些都會影響開發者的體驗。為了解決這些問題,現在出現了一些解決方案,例如 lit-ssr, WebC, Enhance 等,讓我們能夠實現以下兩個目標,更好地創建 Web Components:

  1. 開發者體驗(Developer Experience):讓開發者能夠快速地編寫自定義元素(custom elements),例如 <my-badge variant="success" text="99 Luftballoons">,而且不需要太多的樣板代碼(boilerplate code)。
  2. 使用者體驗(User Experience):讓使用者在沒有 JavaScript 的情況下看到預設內容,當 JavaScript 載入完成後再顯示真正的 Web Components,以獲得漸進增強的體驗。
提示

如果你想了解更多關於 web components 的基本概念,可以參考 Dave’s web components course

The Benefits of Web Components

作者認為,Web Components 的真正優勢在於設計系統元件庫(design system component library)。使用者並不在乎網站採用何種技術,他們只關注能否獲得良好的使用體驗,而要實現這一目標,最重要的是要擁有出色的設計系統元件庫。

為了更好地分類前端,作者將其分為兩個部分:前端的前端(front-of-the-front-end)和前端的後端(back-of-the-front-end)。前者包括 HTML、CSS 和展示性(presentational)的 JavaScript;後者包括不會直接顯示給使用者的程式碼,例如路由、狀態管理和數據提取等。為了創建優秀的「前端的前端」,Web Components 是一個很好的解決方案。Web Components 可以作為傳遞設計系統的載體,讓我們可以在不同的技術中使用相同的設計系統。

Web Components vs Frameworks

作者認為,Web Components 與 JS libraries/frameworks(例如 React、Angular、Vue 等)不是互斥的技術,而是相輔相成的。它們可以一起使用,創建出良好的 Web 體驗。例如,可以使用 Web Components 來建立設計系統,而使用 JS libraries/frameworks 來處理商業邏輯、狀態管理、快取等工作。透過這種切割方式,可以清楚地分離兩者該關注的地方,實現良好的分工效果。