首页 > web前端 > css教程 > 将Web组件与Next(或任何SSR框架)一起使用

将Web组件与Next(或任何SSR框架)一起使用

William Shakespeare
发布: 2025-03-10 11:57:15
原创
403 人浏览过

Using Web Components With Next (or Any SSR Framework)

>我以前的文章探索了Shoelace,这是一个组件库,提供了一套全面吸引人的,可访问的UX组件,该组件使用Web组件构建。 该体系结构允许框架 - 不平衡的用法。虽然React的Web组件集成不是最佳的,但存在解决方法。

> Web组件的一个重大限制是他们目前缺乏服务器端渲染(SSR)支持。 声明性的影子DOM(DSD)正在开发中,但是当前支持是有限的,需要服务器端修改。 Next.js在该领域的开发很有希望。 本文着重于使用当前技术(包括Next.js)在任何SSR框架中管理Web组件。

这种方法涉及手动步骤,并且对初始页面负载有轻微的性能影响。我们将解决绩效优化策略。 该解决方案并非没有权衡。彻底的测试和分析至关重要。

>

挑战:SSR和Web组件

为什么Web组件不与SSR无缝集成?

诸如Next.js Process React代码之类的框架,将组件转换为普通HTML。 React组件树在服务器上渲染,此HTML发送到客户端浏览器。 与此HTML一起是加载React和组件代码的标签。 浏览器重新呈现组件树,将其与服务器渲染的HTML匹配。 这个被称为水合的过程激活效果,事件处理程序和状态管理,使应用程序交互。

> Web组件使它复杂化。 当渲染像鞋带的组件时:

React(或任何JavaScript框架)直接通过这些标签。 渲染逻辑位于Web组件的代码中(在这种情况下为Shoelace)。 此代码执行的时间至关重要。<sl-tab-group></sl-tab-group>>

通常,Web组件注册是通过水合过程中的JavaScript导入的。 这意味着该组件要等到水合后才能正确渲染,从而导致未风格的内容(FOUC)闪烁。 虽然理论上可以添加占位符标记,但它是不切实际的,尤其是在第三方库中。
<sl-tab-group ref="{tabsRef}">
  <sl-tab panel="general" slot="nav">General</sl-tab>
  <sl-tab panel="custom" slot="nav">Custom</sl-tab>
  <sl-tab panel="advanced" slot="nav">Advanced</sl-tab>
  <sl-tab disabled panel="disabled" slot="nav">Disabled</sl-tab>
  <sl-tab-panel name="general">This is the general tab panel.</sl-tab-panel>
  <sl-tab-panel name="custom">This is the custom tab panel.</sl-tab-panel>
  <sl-tab-panel name="advanced">This is the advanced tab panel.</sl-tab-panel>
  <sl-tab-panel name="disabled">This is a disabled tab panel.</sl-tab-panel>
</sl-tab-group>
登录后复制
登录后复制
> hydration Web组件注册

问题是Web组件注册代码的延迟执行直至水合。 我们的解决方案涉及较早地运行此代码。 我们将自定义Web组件代码,并在文档的

中添加阻止脚本。 这通常是不希望的,因为它与SSR的目的相矛盾,但可以确保立即渲染。 缓存将减轻性能的影响。这不是理想的长期解决方案。 Future Next.js DSD支持可能会消除这一需求。

>实现详细信息

完整的代码可在此GitHub存储库中可用,并使用Vercel在此处部署。该应用程序将鞋带组件与文本一起在水合后发生变化。 文本将更新为“水合”,而鞋带组件从一开始就正确呈现。

自定义捆绑

首先,创建一个导入所有Web组件定义的JavaScript模块。对于鞋带:

<sl-tab-group ref="{tabsRef}">
  <sl-tab panel="general" slot="nav">General</sl-tab>
  <sl-tab panel="custom" slot="nav">Custom</sl-tab>
  <sl-tab panel="advanced" slot="nav">Advanced</sl-tab>
  <sl-tab disabled panel="disabled" slot="nav">Disabled</sl-tab>
  <sl-tab-panel name="general">This is the general tab panel.</sl-tab-panel>
  <sl-tab-panel name="custom">This is the custom tab panel.</sl-tab-panel>
  <sl-tab-panel name="advanced">This is the advanced tab panel.</sl-tab-panel>
  <sl-tab-panel name="disabled">This is a disabled tab panel.</sl-tab-panel>
</sl-tab-group>
登录后复制
登录后复制
这个模块不能直接导入;必须定制捆绑,以防止纳入常规的JavaScript束。 我将使用Vite。安装它(

)并创建> npm i vite vite.config.js这将在

中创建一个捆绑包。 将其移至Next.js服务中的
import { setDefaultAnimation } from "@shoelace-style/shoelace/dist/utilities/animation-registry";

import "@shoelace-style/shoelace/dist/components/tab/tab.js";
import "@shoelace-style/shoelace/dist/components/tab-panel/tab-panel.js";
import "@shoelace-style/shoelace/dist/components/tab-group/tab-group.js";

import "@shoelace-style/shoelace/dist/components/dialog/dialog.js";

setDefaultAnimation("dialog.show", { /* ... */ });
setDefaultAnimation("dialog.hide", { /* ... */ });
登录后复制
>文件夹。 节点脚本管理此脚本并创建一个模块导出捆绑文件名:

shoelace-dir和一个相应的NPM脚本:public

import { defineConfig } from "vite";
import path from "path";

export default defineConfig({
  build: {
    outDir: path.join(__dirname, "./shoelace-dir"),
    lib: {
      name: "shoelace",
      entry: "./src/shoelace-bundle.js",
      formats: ["umd"],
      fileName: () => "shoelace-bundle.js",
    },
    rollupOptions: {
      output: {
        entryFileNames: `[name]-[hash].js`,
      },
    },
  },
});
登录后复制
脚本加载

>在Next.js的
// ... (Node script to move the bundle and create a module with the bundle path) ...
登录后复制
中,导入捆绑路径,然后将a

标签添加到

>:

>:_document.js> <script></script> 这可以确保Web组件注册在初始HTML渲染之前运行。

"bundle-shoelace": "vite build && node util/process-shoelace-bundle",
登录后复制
性能优化:缓存

>将缓存标头添加到下一个。

这有效地利用浏览器缓存。

结论
// ... (_document.js with script tag added) ...
登录后复制

虽然此方法需要手动步骤,但它为Web组件和SSR的当前局限性提供了解决方法。 框架 - 不足的组件的好处和使用新框架更容易实验的优势超过了初始实现的复杂性。 Web组件SSR支持的未来改进可能会简化此过程。

>

以上是将Web组件与Next(或任何SSR框架)一起使用的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板