如何在 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';
然后在我们的 JSX/HTML 中使用它:
<div>
<atom-spinner/> Loading
</div>
该 Web 组件将封装行为和样式,而无需框架的负担,这对我们来说非常好。
然而,当涉及到 Next.js 和 TypeScript 时,我们会遇到一些问题。
TypeScript 和 Web Components
当您将 TypeScript 与 JSX 一起使用时,它会尝试检查您使用的每个元素以防止拼写错误。如果您刚刚注册了一个组件,而该组件当然并不存在于正常的 DOM 中,那么这就会成为一个问题:
Property 'atom-spinner' does not exist on type 'JSX.IntrinsicElements'.ts(2339)
我从这个人那里得到的解决方案是使用声明合并来扩展 TypeScript:
// declarations.d.ts - place it anywhere, this is an ambient module
declare namespace JSX {
interface IntrinsicElements {
"atom-spinner": any;
}
}
Next.js 和 Web 组件
接下来你会遇到的问题是服务器端渲染。
ReferenceError: HTMLElement is not defined
众所周知,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>)
}
就这样!祝您使用愉快!
文章来源:https://dev.to/swyx/how-to-use-web-components-with-next-js-and-typescript-4gg1