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

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

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

原文地址:Frontend Masters

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

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

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

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

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

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

像这样:

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

我们该如何集成那些 component.jscomponent.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 ComponentShadow 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 支持,但方向已经很明确了。

相关推荐
风象南4 小时前
我把大脑开源给了AI
人工智能·后端
哈里谢顿7 小时前
1000台裸金属并发创建中的重难点问题分析
面试
哈里谢顿8 小时前
20260303面试总结(全栈)
面试
橙序员小站9 小时前
Agent Skill 是什么?一文讲透 Agent Skill 的设计与实现
前端·后端
怒放吧德德9 小时前
Netty 4.2 入门指南:从概念到第一个程序
java·后端·netty
雨中飘荡的记忆10 小时前
大流量下库存扣减的数据库瓶颈:Redis分片缓存解决方案
java·redis·后端
炫饭第一名11 小时前
速通Canvas指北🦮——基础入门篇
前端·javascript·程序员
开心就好202512 小时前
UniApp开发应用多平台上架全流程:H5小程序iOS和Android
后端·ios
悟空码字12 小时前
告别“屎山代码”:AI 代码整洁器让老项目重获新生
后端·aigc·ai编程
小码哥_常12 小时前
大厂不宠@Transactional,背后藏着啥秘密?
后端