发布于 2026-01-06 1 阅读
0

如何在 Next.js 和 TypeScript 中使用 Web Components

如何在 Next.js 和 TypeScript 中使用 Web Components

今天直播的时候,我需要在我的应用里添加一个加载指示器组件来展示开发进度。但是我发现现有的 React 加载指示器组件太臃肿了。于是,我突然想到,不如在我的 Next.js(React/Preact)应用中第一次尝试使用 Web 组件!

我们将以https://github.com/craigjennings11/wc-spinners/为例进行案例研究。

Web 组件入门

通常情况下,要在项目中使用 Web 组件,只需像导入库一样导入它即可:

  import 'wc-spinners/dist/atom-spinner.js';
Enter fullscreen mode Exit fullscreen mode

然后在我们的 JSX/HTML 中使用它:

<div> 
    <atom-spinner/> Loading
</div>
Enter fullscreen mode Exit fullscreen mode

该 Web 组件将封装行为和样式,而无需框架的负担,这对我们来说非常好。

然而,当涉及到 Next.js 和 TypeScript 时,我们会遇到一些问题。

TypeScript 和 Web Components

当您将 TypeScript 与 JSX 一起使用时,它会尝试检查您使用的每个元素以防止拼写错误。如果您刚刚注册了一个组件,而该组件当然并不存在于正常的 DOM 中,那么这就会成为一个问题:

Property 'atom-spinner' does not exist on type 'JSX.IntrinsicElements'.ts(2339)
Enter fullscreen mode Exit fullscreen mode

我从这个人那里得到的解决方案是使用声明合并来扩展 TypeScript:

// declarations.d.ts - place it anywhere, this is an ambient module
declare namespace JSX {
  interface IntrinsicElements {
    "atom-spinner": any;
  }
}
Enter fullscreen mode Exit fullscreen mode

Next.js 和 Web 组件

接下来你会遇到的问题是服务器端渲染。

ReferenceError: HTMLElement is not defined
Enter fullscreen mode Exit fullscreen mode

众所周知,Web 编辑器 (WC) 的服务器端渲染 (SSR) 性能并不理想。如果需要对 WC 进行 SSR,通常的建议是使用 Stencil.js 之类的框架。但我对此并不了解。

由于我的使用场景只需要客户端的 WooCommerce,所以我发现我可以简单地延迟加载 WooCommerce:

function Component() {
  React.useEffect(() => import("wc-spinners/dist/atom-spinner.js")
  , [])
  return (<div>
        // etc
        <atom-spinner />
        </div>)
}
Enter fullscreen mode Exit fullscreen mode

就这样!祝您使用愉快!

文章来源:https://dev.to/swyx/how-to-use-web-components-with-next-js-and-typescript-4gg1