• 2024年前端框架该用 Web Components还是用主流可靠的 React/Vue?
  • 发布于 2个月前
  • 150 热度
    0 评论
一.为什么想讨论这个话题?
主要归因于 Web Components 的一些优势、Google 团队推出的 Lit 框架以及 React 19 将支持 Web Components。

现在 React/Vue 框架趋于稳定,作为开发者的我们在开始一个项目时,在技术栈选择上常常会犹豫不决。是选择当前主流可靠的 React/Vue?还是选择更轻量时髦的 Svelte 或 Solid?还是选择老派的服务器框架或者 HTMX?

下面以构建博客示例来阐述原因?在选择构建博客时,当时有考虑选择使用 React,但是大多数情况下项目的约束决定了技术选型的决策,在反复的考虑之后,下面谈谈为什么?

写博客时间长的同学,可能都经历过各种技术栈的切换,现在使用的可能是 Astro 构建的,在这之前可能是静态网页生成器构建的,再之前可能是 Hugo,再之前可能是 WordPress。

在博客技术切换的过程中,让迁移变得容易的可能是将所有内容都保存为 Markdown 文件,在不同系统之间切换是只需要从一个系统导出,再导入另一个系统即可,最多的修复下兼容性或者移除一些无法移植的内容。博客系统可以很容易的跑起来。

令人不愉快的是大多数网站生成器都有一种自有的语法糖,Astro 也不例外。MDX 允许你在 Markdown 文件中集成 Astro 组件。这些组件可以使用 Astro 构建系统的所有功能,您可以在一个文件中编写 HTML、CSS 和 JS,Astro 会自动为您提取和优化所有内容。它还会范围化 CSS 选择器,编译 TypeScript,让你有条件地渲染标记,做其他各种花哨的事情。

当然,缺点是这一切只能在 Astro 内部运行。为了切换到不同的网站生成器,我必须重写这些组件。我可能需要拆分 HTML、CSS 和 JS,或者配置新的构建系统,或者找到新的样式范围。因此,Astro 特有的功能是不受限制的--无论多么方便。

不过 Markdown 优势是你可以在其中编写 HTML!这意味着我想添加的任何花哨的交互式图表,只要能用纯 HTML 标签来表达,就能和我的其他 Markdown 一样具有可移植性。

Web Components 恰好满足了这一需求。它们是用于构建可重用 HTML 元素的 W3C 标准集。您通过编写自定义元素的类、注册标签名称并在标记中使用它们来使用它们。下面是编辑器的代码:
<pixelart-demo></pixelart-demo>
Web Components 将所有 HTML、CSS 和 JS 封装在一个文件中,无需构建系统。开发者可以将组件的所有代码集中在一个地方,大大减少了脑力开销,因为它们给开发者带来了良好的体验。虽然 Web Components 不像 Astro 或 Svelte 那样好写,但它们仍然超级方便。

如果您对 Web Components 不熟悉,下面是上述 <pixelart-demo> 组件的代码
import PixelEditor from "./PixelEditor.js";
// 堆代码 duidaima.com
class PixelArtDemo extends HTMLElement {
  constructor() {
    super();

    this.shadow = this.attachShadow({ mode: "closed" });
    this.render();

    const resolution = Number(this.getAttribute("resolution")) || 100;
    const size = { w: resolution, h: resolution };

    const alice = new PixelEditor(this.shadow.querySelector("#alice"), size);
    const bob = new PixelEditor(this.shadow.querySelector("#bob"), size);

    alice.debug = bob.debug = this.hasAttribute("debug");
  }

  render() {
    this.shadow.innerHTML = `
      <div class="wrapper">
        <canvas class="canvas" id="alice"></canvas>
        <canvas class="canvas" id="bob"></canvas>
        <input class="color" type="color" value="#000000" />
      </div>

      <style>
        .wrapper {
          display: grid;
          grid-template-columns: 1fr 1fr;
          grid-template-rows: 1fr auto;
          gap: 1rem;
          margin: 2rem 0 3rem;
        }

        .canvas {
          grid-row: 1;
          width: 100%;
          aspect-ratio: 1 / 1;
          border: 0.25rem solid #eeeeee;
          border-radius: 0.25rem;
          cursor: crosshair;
        }

        .color {
          grid-column: 1 / span 2;
        }
      </style>
    `;
  }
}

customElements.define("pixelart-demo", PixelArtDemo);
Web Components 的另一个优点是 Shadow DOM,它将组件与周围的页面隔离开来。当你想在组件和应用程序的其他部分之间共享样式时,shadow DOM 往往会显得很笨拙,但当你真的想把所有东西都隔离开来时,它就非常完美了。就像图片和视频一样,无论在哪里使用,这些组件的外观和行为都是一样的。同时 Web Components 可以暴露属性,以便从外部对其进行配置。

另一个是使用 vanillaJS。有一些框架可以编译成 Web Components ,其中最著名的是 Lit(虽然我更愿意称它为一个库),但也有 Stencil、Svelte 等。它们都是很棒的工具,但框架是一种依赖关系,而依赖关系又需要权衡利弊。在这种情况下,最担心的就是维护问题。

这一点也适用于 TypeScript。TypeScript 的最近 15 个版本都有破坏性的变化,尽管我们很喜欢 TypeScript,它并不是 Web 的原生底座,它仍然是一个依赖项。使用依赖项是有代价的。新版本会发布、API的变化,都需要花时间和努力确保码与它们兼容。而且这个成本会随着时间的推移而积累。

回顾 Web 发展的 20 年,见证过 jQuery 的诞生、崛起和衰落。Node.js被创造出来,分叉成io.js,然后再次合并到 Node.js 中,还有 Deno、Bun 的出现。Backbone 爆发增长,很快被 AngularJS 取代,然后又被 React 和 Vue 取代,再就是新兴框架的出现 Lit、Astro、Svelte、Solid 等。jQuery 4.0.0 要来了;Rsbuild 0.4 正式发布;Shiki v1.0 发布,一个轻量且强大的语法高亮工具!

但是,在其周围的生态系统不断变化的同时,Web 平台本身却保持了非常稳定 - 这在很大程度上是因为标准的管理者辛苦工作,确保没有新的变化会破坏现有的网站。比如,1996年的原始《Space Jam》网站仍然有名且在现代浏览器中完美呈现。

二.2024年的 Web Components
2024年“W3C Web Components 社区小组”举行了面对面会议,讨论了 Web Components 标准和平台相关改进。

2.1.声明式 Shadow DOM (DSD)
最新消息,Firefox 已批准在 2 月 20 日发布的 123 版本支持声明式 ShadowDOM。至此,声明式 ShadowDOM 将被所有现代浏览器所支持!重要通知,尽快迁移至 NPM 淘宝镜像新域名!对于 Web 开发人员,Firefox 做到了!

如果您对 DSD 还不熟悉,它是一种新的标准,可以在 HTML 中创建 Shadow DOM,而无需编写任何 JavaScript。声明式Shadow DOM 可以实现许多有趣的应用场景:
.使用完全封装的样式和基于插槽的组合的伪自定义组件,无需 JavaScript。
.无需 JavaScript 的无序、延迟内容流。
.改进了语义与展示目的的 HTML 声明性分离。
.服务器渲染 Web 组件的标准输出。
.从全局 CSS 技术向性能更强的模块化 CSS 迁移的改进路径。
.改进迁移路径,采用更现代、面向组件的 HTML 架构。

.新的渐进增强方法。


2.2.CSS 插槽内容检测
在构建 Web 组件或使用 Shadow DOM 时,经常需要根据某些内容是否插入特定位置来改变样式。例如,设想一个按钮组件需要根据图片是否插入按钮来改变其内部间距。如今,可以通过向 slotchange 事件添加事件监听器,并根据 assignedNodes() 来更改样式来实现这一目的。

由于这种情况非常普遍,Web 组件 CG 一直在与 CSS WG 和浏览器供应商合作,通过一种新的完全声明式机制来扩展 CSS,从而实现基于插槽状态的样式设计。

在 CSS 中,有多种方法可以解决这个问题,比如使用组合器或伪选择器。虽然组合器的功能更强大,但也可能会导致严重的复杂性甚至性能问题。有鉴于此,该小组似乎更倾向于采用更简单的方法,即使用一种在范围上非常有针对性的伪选择器,这样可以更快地推出,风险也更小。该小组正在 W3C 跟进下一步工作,以便在这些讨论之后制定出正式规范。

2.3.作用域元素注册表
如今,所有自定义元素都是在 HTML 中全局定义的。虽然这对许多网站和中小型应用程序来说都很合适,但在大型模块化应用程序、迷你应用程序、微前端和其他更复杂的应用场景中,这就成了一个难题。为了满足这一需求,提出了创建组件范围注册表并将其与阴影 DOM 关联的功能。

幸运的是,去年年底,范围注册表功能在 Chromium 中成功实现了原型。这使得一些悬而未决的问题和重要细节得以解决。CG 同意,下一步将根据从原型中吸取的经验教训更新规范,并在其他浏览器中构建更多原型。我们正在积极召集人手来实现这一目标,已经有志愿者站出来实现跨浏览器。

2.4.ARIA 混合元素
随着 Firefox 119 于 2023 年 10 月发布,现在所有主流浏览器都已支持通过 ElementInternals 进行 ARIA Mixin 字符串反射。这意味着可以通过 ElementInternals 设置基于字符串的 ARIA 属性,而无需在元素主机上手动创建属性,从而使 HTML 更简洁,并使组件消费者能够用自己的设置覆盖默认的 ARIA 设置。

最后
2024年,Web Components 将会得到进一步的发展,作为开发者的我们可以有更多期待。不管是使用 Web Components 还是主流框架 React/Vue,在我们做项目技术选型时,建议是从项目情况、团队人员能力水平、技术栈的发展等不同维度来评估。
用户评论