Web Components:原生组件化开发新趋势
上周五晚上十点半,我关掉最后一台云服务器的监控面板,从工位上站起来,腰椎一阵刺痛。窗外成都的夜雨淅淅沥沥,楼下烧烤摊的灯光在雾气中晕开一圈暖黄。手机震动,是老婆发来的消息:“今天又加班到这么晚?锅里给你留了汤。”
我苦笑了一下,回了个“嗯”,然后瘫在椅子上,盯着屏幕上那堆 React 组件代码发呆。这已经是这个月第 12 次线上 bug 回滚了,起因是一个看似微不足道的 props 传递问题,却因为层层嵌套的组件树,导致整个产品页面白屏。那一刻,我突然想起三年前被裁那天,也是这样一个雨夜。
那是 2021 年 10 月,我还在一家中型互联网公司做前端组长,月薪 18k,房租 3500,生活还算安稳。但那天 HR 找我谈话,说公司战略调整,我们整个前端团队被裁掉一半。我抱着纸箱走出写字楼时,成都的秋天冷得刺骨。回家路上,老婆打来电话,声音有点发抖:“房贷下个月要还 6800,你……有打算吗?”
接下来的三个月,我投了 87 份简历,面试了 11 家公司,最长一次等了两周没回音。最焦虑的时候,我甚至考虑过转行去教 Python 网络爬虫——毕竟大学时主修的是后端,Python 写得比 JavaScript 还溜。但最后,还是咬牙接了现在这家公司的 offer,月薪 15k,比之前低了 3k,但好歹稳住了生活。
入职后,我接手了一个老项目重构。技术栈是 React + TypeScript,但代码混乱得像一锅四川麻辣烫——各种 HOC、render props、Context 嵌套得让人眼花缭乱。产品经理小王是个急性子,总在站会上拍桌子:“这个功能下周必须上线!用户等不及了!”
可现实是,我们连一个简单的按钮样式都要改三个文件,因为被封装在三层高阶组件里。更糟的是,和后端联调时,他们用 Python 写的接口返回格式经常变动,而我们的前端组件强依赖特定结构,每次后端一改,前端就得跟着大改。
那段时间,我天天失眠。凌晨三点躺在床上,脑子里全是虚拟 DOM 的 diff 算法和组件生命周期。老婆看我状态不对,劝我:“要不咱们回老家?成都工资低,但生活成本也低,压力小点。”我摇摇头,心里清楚:程序员这行,一旦停下,再想追上技术浪潮就难了。
转机出现在去年三月。公司接了个政府项目,要求所有前端模块必须能独立部署、跨框架复用。React 团队和 Vue 团队吵得不可开交,最后技术总监拍板:“试试 Web Components 吧,原生支持,不用依赖框架。”
说实话,一开始我对 Web Components 有偏见。总觉得它“太原始”,API 繁琐,兼容性差,远不如 React 那样“优雅”。但迫于项目压力,我硬着头皮啃了 MDN 文档,写了第一个自定义元素:
class MyButton extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
button { background: #007bff; color: white; border: none; padding: 8px 16px; }
</style>
<button><slot></slot></button>
`;
}
}
customElements.define('my-button', MyButton);
简单吧?但它最大的魔力在于——完全独立于框架。我在 React 项目里直接写 <my-button>提交</my-button>,Vue 项目里也能用,连后端同事用 Python Flask 渲染的静态页面都能嵌入。
更让我惊喜的是,它和产品需求天然契合。以前产品经理提一个“全局统一的弹窗组件”,我们得在 React 里封装,再让 Vue 团队照着抄一遍,两边样式还不一致。现在,我们只维护一个 Web Component,通过属性(attributes)和事件(events)通信,真正做到了“一次开发,到处使用”。
举个例子,我们做了一个 <data-table> 组件,支持动态列配置、分页、排序。后端用 Python 生成 JSON 配置,前端直接传给组件:
<data-table config-url="/api/table-config" data-url="/api/user-data"></data-table>
组件内部自己 fetch 数据,渲染表格,点击分页按钮时派发自定义事件,主应用监听即可。前后端解耦了,框架也解耦了。产品经理小王终于不再在群里@所有人问“这个功能什么时候能用在 A 系统和 B 系统?”
当然,Web Components 也不是银弹。没有虚拟 DOM,性能在极端场景下确实不如 React;状态管理得自己搞,不像 Redux 那样成熟;调试工具也不如 React DevTools 友好。但你知道吗?有时候,少即是多。
我渐渐发现,很多前端复杂度,其实是我们自己“造”出来的。为了追求“工程化”,我们引入了无数抽象层,结果反而让简单的事情变得复杂。而 Web Components 把组件回归到最本质:一个可复用的 UI 单元,有输入、有输出、有样式、有行为。
现在,我带领的小组已经把核心 UI 元素全部用 Web Components 重写。React 应用里,我们只用它来处理业务逻辑和路由,UI 层全靠原生组件。代码量少了 40%,bug 率大幅下降,连测试都变简单了——毕竟每个组件都是独立的“黑盒”。
上个月,我拿到了晋升通知,月薪涨到 22k。虽然在成都依然不算高,但至少不用再为下个月的房贷发愁。那天晚上,我请老婆吃了顿火锅,她笑着说:“你最近气色好多了,是不是不那么焦虑了?”
我点点头,夹了片毛肚:“是啊,感觉终于找到了一条‘不卷’的路。”
回望这段路,我最大的感悟是:技术选型不该盲目追随潮流,而要服务于产品和团队的真实需求。
React 很强大,但不是所有场景都需要它的全套生态。Python 在后端很灵活,但前端不该被后端的数据结构绑架。而 Web Components,就像一个沉默的桥梁,让不同技术栈之间能够和平共处,让开发者把精力放在解决业务问题上,而不是框架之争。
如果你也在维护一个“祖传”前端项目,或者被跨框架复用折磨得睡不着觉,不妨试试 Web Components。它可能不够“酷”,但足够“稳”;它可能不够“新”,但足够“实”。
在这个充满不确定性的时代——裁员潮、AI 冲击、35 岁危机——我们程序员最需要的,或许不是追逐下一个风口,而是找到一种可持续、可维护、能让生活回归平静的开发方式。
成都的雨还在下,但我的心里,已经放晴了。

评论 0