首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >使用 Web Components 与 CSS Modules 构建原生应用架构

使用 Web Components 与 CSS Modules 构建原生应用架构

作者头像
掘金安东尼
发布2026-06-12 08:14:44
发布2026-06-12 08:14:44
630
举报
文章被收录于专栏:掘金安东尼掘金安东尼
image.png
image.png

公认的好方案™:在构建任何形式的数字信息页面时,最佳实践是通过组件,再由这些组件组合成完整的界面。这个可以有很多种细分方式,但通常来说:一个组件就是该界面所需功能中一个相对独立、合理的部分。比如在网站中,像页眉、页脚、网格、卡片、按钮等元素,就可以看作一个个组件。这也就是所谓的设计系统。相关概念可以参考“原子设计”(Atomic Design)。

JavaScript 框架兴起带来的一个意外收获是,它们进一步巩固了这一理念。ReactVueSvelte……你使用它们的方式就是通过构建组件并将它们组合在一起。这正是它们的核心所在。

我十分认同这样一种理念:像 JavaScript 框架这样的用户态工具不断突破边界,进而推动 Web 平台本身的演进,最终使其不再依赖这些工具。那么,我们是否能够构建一个基于组件化结构的项目,且完全不依赖构建流程与框架?我们离这个目标很近了。

这是我想要构建网站的示例:

img.png
img.png

这些组件(在我们的简单示例中,按钮、卡片和标题)都是:

  • 在文件夹内components,每个文件夹都有自己命名的文件夹(有组织结构!)
  • 有一个用于其模板和逻辑的文件
  • 有一个单独的 CSS 文件

像这样:

img_1.png
img_1.png

这种逻辑上的分组和隔离,是我觉得在搭建组件架构时比较合理的方式。更复杂的项目里,一个组件可能还会有 .graphql 文件自己的图片测试用例等等。而把相关文件同地部署真的很重要,能让代码更容易维护。

我们该如何集成那些 component.jscomponent.css 文件呢?这个问题困扰了我很久。 打包工具可以完成这项工作。例如 webpack 发明了一套自己的处理方法。如果你在一段由 webpack 处理的 JavaScript 文件里写上 import "./card.css";webpack 就会明白你的意思,并以某种方式确保这个 CSS 文件最终被加载到页面上。 同样地,Vite 也有它自己的一套处理机制:

导入 .css 文件时,打包工具会通过 <style> 标签将其内容注入到页面中,并支持热更新。

这很棒,但我们现在想尝试的是原生方式。没有打包/构建流程。我们该如何导入这样的 CSS 呢?

引入 CSS 模块脚本

好消息: JavaScript 对我们刚刚提出的问题已经给出了解决方案,它被称为 CSS 模块脚本。

坏消息: 只有 Chrome 支持它。(WebKit 异常;Firefox 异常)

谷歌的博客文章是为数不多的关于它们的信息之一,其中还包含一些 错误的语法 ,所以要小心。它应该是这样的(如果你看到 assert 它是过时的/错误的,with关键字是正确的):

代码语言:javascript
复制
import sheet from './styles.css' with { type: 'css' };

当您这样做时(在支持该特性的浏览器中),sheet 就会成为一份“可构造样式表”,然后您可以使用它,在我们的例子中,将其应用到一个 Web ComponentShadow Root 上。

代码语言:javascript
复制
class MyComponent extends HTMLElement {
  constructor() {
    super(); 
    const shadowRoot = this.attachShadow({ mode: 'open' });
    shadowRoot.adoptedStyleSheets = [sheet];
  }

  ...

这些的“导入属性(import attributes)”,我认为它们应该这么称呼,其实还能做其他事情。以这种方式导入 JSON 会得到更好的支持,例如:

代码语言:javascript
复制
import sheet from './data.json' with { type: 'json' };

Lit

使用 Lit 应用 styleset(或“通过 CSS 模块脚本导入的可构造样式表”)来完成整个过程,如下所示:

代码语言:javascript
复制
import {html, LitElement} from 'lit';
import sheet from './button.css' with { type: 'css' };

class My Component extends LitElement {
  static styles = [sheet];

  ...

Demo

image.png
image.png

点评

我们靠 React、Vue、Svelte 等框架来实现网页,现在浏览器也在慢慢补上,给出了原生的方案,比如 CSS 模块脚本:可以像导入 JS 一样直接 import CSS 文件,还能和 Web Components 的 Shadow DOM 配合使用,实现真正无依赖的组件架构。虽然目前只有 Chrome 支持,但方向已经很明确了。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-08-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引入 CSS 模块脚本
  • Lit
  • Demo
    • 点评
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档