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

本篇依然来自于我们的 《前端周刊》 项目!

由团队成员 田八 翻译,欢迎大家 进群 持续追踪全球最新前端资讯!!

原文地址:Frontend Masters

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

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

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

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

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

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

像这样:

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

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

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

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

引入 CSS 模块脚本

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

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

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

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

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

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

  ...

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

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

Lit

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

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

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

  ...

Demo

codepen.io/editor/chri...

点评

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

相关推荐
ShineWinsu4 小时前
对于JavaScript:操作元素的解析
开发语言·前端·javascript·面试·web·dom·元素
马良神笔4 小时前
2026 年Rag最近技术前沿总结
后端·python·django
程序猿DD4 小时前
同样10美元,OpenDesign和Command Code的DeepSeek V4.1 Flash额度到底有多少?
后端
高频因子挖掘机5 小时前
A股量化从日线升级到5分钟线:数据量增加后最先暴露哪些工程问题?
后端·github·api
高频因子挖掘机5 小时前
历史行情返回顺序变了,为什么按行号计算指标很危险?
后端·github·api
团子哒哒6 小时前
数组、切片和Map
后端
专注仿真7 小时前
ThinkPHP6 API接口开发实例:从零搭建RESTful风格接口
后端·php·restful
开心猴爷7 小时前
应对iOS审核4.3:可以使用 IpaGuard 来给属性名混淆的技术细节与平衡之道
后端·ios
1m555555557 小时前
RAG 工程实战(五):正确知识已经进入 Prompt,为什么大模型还是会答错?
后端·面试
CoderYanger7 小时前
Java EE 进阶:4.Spring Web MVC 入门(第一弹)
java·开发语言·前端·spring·面试·java-ee·mvc