Web Components:原生组件化开发新趋势?别被“新”字骗了,我差点又交了智商税
大家好,我是小张,一个从二本毕业、靠自学和死磕面试题逆袭进上海某一线大厂的Java后端开发。现在和女朋友合租在浦东张江,房租3500(没错,是合租,而且还是老破小的一室户隔出来的次卧)。月薪从之前外包公司的15k涨到了现在的22k,听起来挺光鲜,但说实话,每天加班到九点,回家还得刷LeetCode的日子,真没那么爽。
今天不是来晒offer的——虽然去年十月拿到大厂offer那天,我和女朋友在楼下全家便利店一人啃了个饭团庆祝,连瓶可乐都没舍得买(她说“省点钱,以后要结婚的”)。我想聊点技术,一个最近在前端圈里被吹上天的概念:Web Components。
一场深夜的“技术焦虑”
事情得从上周五晚上说起。
那天刚改完一个线上bug(又是那种“用户登录后头像不显示”的祖传问题),拖着疲惫的身体回到家,已经快十一点了。女朋友还在追《黑暗荣耀》第二季,见我回来,递给我一碗热汤:“你今天脸色不太好。”
我说:“没事,就是又被前端同事教育了。”
她笑:“你一个Java后端,怎么老跟前端较劲?”
我苦笑:“因为我们组现在搞微前端,他们说要用 Web Components 来封装通用组件,还说我‘不懂前端现代化’……”
其实我心里有点慌。虽然主职是后端,但大厂讲究全栈能力,尤其我们这种业务中台团队,前后端边界越来越模糊。更扎心的是,上个月部门内部分享会上,一个985硕士出身的前端小哥讲 Web Components,PPT 里全是 <custom-element>、Shadow DOM、HTML Templates,底下一群人点头如捣蒜,就我一脸懵。
回家路上我就想:是不是我又落后了?
于是那晚,我泡了杯速溶咖啡(超市特价8块钱三包那种),打开 MacBook,开始疯狂搜索 Web Components。
别被“新趋势”吓到,它其实很“老”
先说结论:Web Components 根本不是什么新东西!
它最早在 2011 年就被 Google 提出来,2014 年左右就有草案,2017 年主流浏览器基本支持。也就是说,这玩意儿比我第一份工作还早。
但为什么现在突然火了?
原因很简单:React/Vue 的组件模型太成功了,大家开始反思——能不能不用框架,直接用浏览器原生能力实现组件化?
Web Components 就是答案。它由三部分组成:
- Custom Elements(自定义元素):让你能写
<my-button>这种标签。 - Shadow DOM:隔离样式和 DOM,避免全局污染。
- HTML Templates:用
<template>标签预定义结构,按需渲染。
听起来是不是有点像 Vue 的单文件组件?对,就是那个味道,但它是浏览器原生支持的,不需要打包、不需要虚拟 DOM、不需要 npm install。
我当时看到这里,眼睛一亮:这不就是“轻量级、无依赖、跨框架”的终极方案吗?
动手试试?结果差点翻车
周六一早,我决定自己写个 Web Component 玩玩。
目标很简单:做一个带 loading 状态的按钮 <loading-button>。
代码写起来其实不难:
class LoadingButton extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
button { padding: 8px 16px; }
.loading { opacity: 0.6; cursor: not-allowed; }
</style>
<button id="btn">
<slot></slot>
</button>
`;
this.btn = this.shadowRoot.getElementById('btn');
this.btn.addEventListener('click', () => {
if (!this.loading) {
this.setLoading(true);
// 模拟异步操作
setTimeout(() => this.setLoading(false), 2000);
}
});
}
setLoading(loading) {
this.loading = loading;
this.btn.classList.toggle('loading', loading);
this.btn.disabled = loading;
}
}
customElements.define('loading-button', LoadingButton);
然后在 HTML 里直接用:
<loading-button>提交</loading-button>
跑起来居然真行了!没有 React,没有 Vue,连 webpack 都没用,就一个 HTML 文件加一段 JS。
我激动地发给女朋友看:“你看!这就是未来!”
她看了一眼,说:“所以……你折腾一上午,就为了做个按钮?”
我:“……”
那一刻我突然清醒了:技术再酷,也得看场景。
现实很骨感:生态、工具链、开发体验全是坑
冷静下来后,我开始查 GitHub 上的 Web Components 项目。
结果发现:
- 大多数 star 数不过千,更新频率极低。
- 主流 UI 库(比如 Ant Design、Element Plus)根本没有 Web Components 版本。
- 调试体验极差:Shadow DOM 里的元素在 DevTools 里藏得深,样式覆盖要加
::part或::slotted,反人类。 - 没有状态管理、没有响应式更新(得手动操作 DOM)、没有 JSX 语法糖,写复杂逻辑简直折磨。
最致命的是:没人用。
我在 GitHub 搜 “web components production”,前几页全是 demo 和玩具项目。真正用于大型产品的,屈指可数。Google 自己的 Polymer 项目都凉了,现在推的是 Lit(一个基于 Web Components 的轻量库),但社区声量远不如 React。
我突然想起去年面字节的时候,面试官问我:“你怎么看待 Web Components?”
我当时背了标准答案:“它是浏览器原生组件化方案,有利于跨框架复用……”
面试官笑了笑,说:“那你用过吗?”
我说:“没在生产环境用过。”
他说:“很好,诚实比瞎吹强。”
现在我才明白他的意思:技术选型不是看它多“先进”,而是看它能不能解决实际问题。
但 Web Components 真的一无是处吗?
也不是。
我发现它在某些场景下特别香:
1. 微前端中的“胶水层”
我们组做微前端,不同子应用用不同技术栈(有的 Vue 2,有的 React 16)。如果每个子应用都要实现一套“通知弹窗”、“用户头像”组件,维护成本爆炸。
这时候,用 Web Components 写一套通用 UI 组件,所有子应用都能直接用,无需关心内部实现。因为它是原生 HTML 元素,Vue/React 都能无缝集成。
比如:
<!-- Vue 里直接用 -->
<user-avatar user-id="123"></user-avatar>
// React 里也一样
<user-avatar user-id="123" />
完美解耦!
2. 嵌入第三方网站的“小部件”
比如你公司要做一个 SaaS 工具,客户希望在自己的网站上嵌入一个“在线客服”按钮。你总不能让客户装 React 吧?
这时候,打包一个 Web Component 发给他们,一行 script + 一个自定义标签搞定:
<script src="https://your-cdn.com/chat-widget.js"></script>
<chat-widget api-key="xxx"></chat-widget>
干净、独立、无副作用。
3. 爬虫友好?别做梦了
说到爬虫,有人吹 Web Components 对 SEO 友好,因为是原生 HTML。
纯属扯淡。
搜索引擎爬的是最终渲染的 DOM。如果你的 Web Component 是动态加载的(比如通过 JS 注册),那爬虫看到的只是一个空标签 <my-component></my-component>,内容全是 JS 渲染出来的,和 SPA 没区别。
除非你做 SSR(服务端渲染),但 Web Components 本身不支持 SSR,得靠 Lit 或其他上层框架兜底。
所以,别指望靠它提升 SEO。
我的开发心得:别盲目追新,先搞清“为什么”
作为一个从二本逆袭的人,我深知“信息差”有多可怕。
刚毕业那会儿,看到别人聊 Docker、K8s、Serverless,我就焦虑得睡不着觉,觉得自己落后了。结果进了大厂才发现,90% 的业务系统,CRUD + MySQL + Redis 就够了。
技术永远在变,但解决问题的能力才是核心。
Web Components 也一样。它不是银弹,但在特定场景下,确实能带来价值。关键是你得问自己:
- 我的需求是什么?
- 当前技术栈能否满足?
- 引入新技术带来的收益,是否大于学习和维护成本?
去年我面大厂时,HR 问我期望薪资。我说:“20k 吧。”
她笑着说:“你背景一般,但项目经验很扎实,我们给 22k,希望你带来实际产出,而不是只会追新框架。”
这句话我一直记着。
给想学 Web Components 的朋友几点建议
- 先掌握基础:确保你熟悉 HTML、CSS、JS(尤其是 ES6+),否则直接上手 Web Components 会很痛苦。
- 从小工具开始:别一上来就想重构整个项目。先写个日期选择器、提示框试试水。
- 别裸写:推荐用 Lit(Google 出的),它提供了响应式、模板语法等便利功能,开发体验接近 Vue。
- 关注兼容性:虽然现代浏览器都支持,但如果你的用户还在用 IE(别笑,有些政企项目真有),那就别想了。
- GitHub 上找灵感:搜
web-components examples,看看别人怎么用。但记住:demo ≠ production。
最后:技术人的成长,从来不是靠“新”,而是靠“深”
写这篇文章的时候,已经是凌晨一点。女朋友早就睡了,桌上那碗汤凉了。
我关掉编辑器,看了眼窗外——浦东的夜景依旧灯火通明,无数程序员还在加班。
回想自己从二本到大厂的路,其实没什么秘诀。就是认准一个方向,死磕到底。面试前刷了 200 道算法题,写了 5 个 GitHub 开源项目(虽然 star 不多,但都是完整可运行的),面了 17 家公司才拿到 offer。
Web Components 也好,React Server Components 也罢,技术永远只是工具。真正让你值钱的,是你用工具解决问题的能力。
所以,别被“新趋势”绑架。静下心,把手头的业务做好,把代码写干净,把 Bug 修彻底——这些看似 boring 的事,才是你立足的根本。
共勉。
P.S. 如果你也在上海打拼,欢迎留言交流。最近在研究如何用 Web Components 做一个跨框架的埋点 SDK,有兴趣一起搞的可以私信我。GitHub 仓库我下周开源,star 不重要,能帮到人就行。
P.P.S. 明天又要加班,女朋友说周末带我去吃小杨生煎,前提是“不准再谈技术”。唉,程序员的浪漫,大概就是——她愿意听你讲 bug,但只限于饭前五分钟。

评论 0