🧩 Web Components
一句话定性
Web Components 是浏览器试图把”组件化”从框架手里收编为平台原生标准的一次努力。它的理念近乎完美——跨框架、零运行时、永久兼容,正是 Web平台能力演进史 母题的标准剧本。但它也是整条母题里最刺眼的反例:标准赢了理念,却输掉了生态。它没能像 React/Vue 那样统治应用层,最终退守为”设计系统与跨框架基础库的底层管道”。
一、它是什么 & 出现的时代
Web Components 不是一个 API,而是三个相互独立、可组合的浏览器标准:
| 标准 | 作用 | 类比框架里的什么 |
|---|---|---|
| Custom Elements | 自定义 HTML 标签 <my-card>,带生命周期回调 | 组件定义、mounted/componentDidMount |
| Shadow DOM | 给组件一个封装的、样式隔离的子 DOM 树 | CSS Modules / Vue scoped 样式 |
HTML Templates (<template>) | 声明可复用、不立即渲染的 DOM 片段 | JSX / 模板 |
时间线:概念由 Google 团队在 2011 年前后提出(随 Polymer 项目),但第一版规范(v0)设计有缺陷、各厂商分歧大,迟迟无法统一。真正可用的是 Custom Elements v1 / Shadow DOM v1,约 2016 年定稿、2018 年前后四大浏览器普及——这个时间点至关重要(见第五节)。
二、为什么会出现(解决上一代什么痛点)
Web Components 要解决的,是 2013-2018 SPA时代 框架割裂带来的两个真实痛点:
痛点一:框架私有组件模型,彼此不通
React 的组件是 React 的,Vue 的组件是 Vue 的,Angular-2+ 的又是另一套。一个用 React 写的日期选择器,无法直接塞进 Vue 项目。大公司内部多技术栈并存时,UI 组件被迫为每个框架各写一遍。
Web Components 的设想很美:用浏览器原生标准定义组件,任何框架都能用
<my-datepicker>直接消费。一次编写,处处运行——这正是平台收编框架功能的经典动机。
痛点二:没有真正的样式/DOM 封装
母题视角:组件化、样式封装,都是框架/社区先跑通(React 组件、scoped CSS),平台事后用 Custom Elements / Shadow DOM 追认。和 ES-Modules 追认 CommonJS 是同一个故事。
三、核心机制 & 为什么重要
class MyCard extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' }); // ← Shadow DOM:样式隔离
shadow.innerHTML = `<style>p{color:red}</style><p>原生组件</p>`;
}
connectedCallback() { /* 挂载时,类似 mounted */ }
disconnectedCallback() { /* 卸载时 */ }
}
customElements.define('my-card', MyCard); // ← Custom Elements:注册标签之后在任何框架或纯 HTML 里写 <my-card></my-card> 都能用。
为什么这在理念上是"正确"的
- 跨框架:它是 HTML 标准,不属于任何框架 → 天然可复用。
- 零运行时:不需要加载 React/Vue 运行时,浏览器直接认。
- 永久兼容:符合 Web 向后兼容铁律,今天写的 Custom Element,十年后浏览器依然认(对比:框架大版本升级常带破坏性变更)。
从第一性原理看,Web Components 几乎是组件化的”理论最优解”。这恰恰让它的失败更值得深究。
四、带来的新问题 / 局限
Web Components 的硬伤,不在理念,而在它只提供了”原语”,却没提供”开发体验和配套”:
致命的能力缺口
缺口 框架早已解决,Web Components 当年没有 声明式数据绑定 React/Vue 有响应式;原生 Custom Element 要手写 attributeChangedCallback+ DOM 操作,退回命令式状态管理 框架有完整状态方案;Web Components 标准对此只字不提 SSR(服务端渲染) Shadow DOM 长期无法在服务端序列化(Declarative Shadow DOM 直到 2023 才落地),对 SEO/首屏是灾难 属性 vs 特性(prop vs attribute) HTML attribute 只能传字符串,传对象/数组要绕弯,与框架的 props 心智冲突 开发体验 没有 JSX/SFC 那样的模板语法糖,写起来啰嗦;调试工具滞后
二阶效应:它给了"原语",却把"造体验"的活又丢回给了社区
Web Components 是一套底层积木,不是一个能直接盖房子的框架。结果是:开发者想用它做真实应用,还得自己补响应式、状态、路由——这不就是又要造一个框架吗? 于是 Google 自己出了 Polymer,后来演进为 Lit(一个轻量库,给 Web Components 补上响应式与模板)。这恰恰证明了:光有标准原语不够,你仍然需要一层框架。
五、为什么没有彻底成功 / 现状(客观)
这是本篇的核心。Web Components 输给 React/Vue,输的不是理念,是时机和生态:
三个致命的"晚了一步"
- 生态窗口期已关闭:Custom Elements v1 到 2018 年才普及。而 React(2013)、Vue(2014)早已占领开发者心智、建好全家桶。当平台姗姗来迟,开发者的家已经在框架里安好了——生态有网络效应和迁移成本,搬不动。
- DX 差了一个数量级:同一时期,React 有 JSX、Hooks、DevTools、海量教程和组件库;Web Components 还在让你手写
attributeChangedCallback。开发者用脚投票。- 关键能力补齐太晚:SSR(Declarative Shadow DOM)拖到 2023 才像样,而那几年正是 SSR/SSG 回归(渲染模式演进史)的大潮——错过了最需要它的时间窗。
理念:跨框架 / 零运行时 / 永久兼容 ────► 几乎完美
│
实践:DX 差 + 缺状态/SSR + 来得太晚 ────► 应用层全面败给 [[React]]/[[Vue]]
│
↓
退守:不做"应用框架",做"底层管道"
现状:它没死,而是"沉"到了底层
Web Components 没有统治应用开发,但在一个领域赢得很彻底——跨框架的设计系统与基础组件库:
- Lit(原 Polymer):用最薄的一层把 Web Components 变好用,是当下写 WC 的主流方式。
- 大厂设计系统:Adobe Spectrum、SAP UI5、GitHub(部分 UI)、微软 FAST/Fluent 等,都用 Web Components 做框架无关的组件底座——因为它们要同时服务 React/Vue/Angular/纯 HTML 的消费方,跨框架正是它唯一不可替代的杀手锏。
shadcn/ui路线的反面:对比 shadcn-ui 把组件源码塞进你的 React 项目,Web Components 走的是”框架无关的运行时分发”——两种哲学,各有其位。一句话:Web Components 没赢得开发者的日常,但赢得了”必须跨框架”的那个利基。 它从”组件化的未来”降级为”组件化的最大公约数”。
六、对后续技术的影响(因果链)
框架割裂:[[React]]/[[Vue]] 组件互不相通 + 全局 CSS 泄漏
│
↓
平台收编:Web Components 三件套(Custom Elements + Shadow DOM + Templates)
│ 理念完美:跨框架 / 零运行时 / 永久兼容
│
├──► 但缺响应式/状态/SSR,DX 差,且 v1 普及(2018)晚于 React/Vue 心智占领
│ │
│ └──► 应用层之争:全面败给框架(标准赢理念,输生态)
│
├──► Polymer → Lit:补一层薄框架,让 WC 真正可用
│
└──► 沉为底层:大厂"框架无关设计系统"的标准底座(Adobe/SAP/微软…)
│
↓
与 [[ES-Modules]]、原生 CSS 能力一起,构成"平台原生能力反哺框架"的潮汐
│
↓
指向 [[未来5到10年前端发展方向]]:平台越来越强,框架越来越薄
(但 DX 与生态惯性,决定框架不会消失)
历史地位:一面照出"标准 ≠ 胜利"的镜子
Web Components 是 Web平台能力演进史 里最深刻的教训:技术先进性从来不是胜利的充分条件。它在每一条第一性原则上都赢了 React/Vue——跨框架、零运行时、永久兼容——却因为晚了几年、DX 差一截、配套缺一块,被生态惯性挡在了应用层之外。这和 ECMAScript演进史 反复证明的道理一致:Web 上真正决定成败的,不是”谁更对”,而是”谁先到、谁更好用、谁的生态更厚”。
🔗 本组:Web平台能力演进史 | PWA | WebAssembly | Service-Worker与离线能力 🔗 同一母题:ECMAScript演进史 | ES-Modules 🔗 框架对照:React | Vue | Svelte | 前端框架演进史 | shadcn-ui 🔗 时代:2013-2018 SPA时代 | 2018-2023 工程化时代 🔗 浏览器/趋势:Chrome | 浏览器演进史 | 未来5到10年前端发展方向