Svelte+Vite运行npm run dev报HTMLElement is not defined错误求助
问题:Svelte项目中Web Components报「HTMLElement is not defined」错误
执行npm run dev(实际为vite dev)后出现如下错误:
HTMLElement is not defined ReferenceError: HTMLElement is not defined at /src/components/shared/formkit/classes/composite.js:21:39 at async instantiateModule (file:///D:/my_project/node_modules/vite/dist/node/chunks/dep-0fc8e132.js:50548:9)
问题代码位于composite.js第21行:
// File name is composite.js export class FormKitComposite extends HTMLElement {
该功能在Storybook中可正常运行,无报错。
相关配置文件
tsconfig.json
{ "extends": "./.svelte-kit/tsconfig.json", "compilerOptions": { "allowJs": true, "checkJs": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "noImplicitAny": true, "noUnusedLocals": true, "resolveJsonModule": true, "skipLibCheck": true, "sourceMap": true, "strict": true, "types": [ "@testing-library/jest-dom", "vitest/globals" ] }, "include": [ "decs.d.ts" ] }
vite.config.ts
const config: UserConfig = { plugins: [sveltekit()], resolve: { alias: { $components: path.resolve('src/components'), $functions: path.resolve('src/functions'), $graphql: path.resolve('src/graphql'), $stores: path.resolve('src/stores'), $styles: path.resolve('src/styles'), $types: path.resolve('src/types') } }, server: { fs: { strict: false } }, test: { environment: 'jsdom', globals: true, include: ['src/components/**/*.test.ts', 'src/functions/**/*.test.ts'], setupFiles: ['./setup-test.ts'], coverage: { branches: 100, functions: 100, lines: 100, statements: 100 } } };
解决方案
错误核心原因是:SvelteKit默认在服务端渲染(SSR)阶段执行代码,而Node.js环境不存在浏览器特有的HTMLElement对象;Storybook是纯浏览器环境,因此不会触发该问题。以下是几种可行的解决方法:
1. 仅在客户端导入Web Components代码
方式A:用onMount动态导入
在Svelte组件中通过onMount钩子(仅在客户端执行)导入Web Components类:
<script> import { onMount } from 'svelte'; onMount(async () => { const { FormKitComposite } = await import('$components/shared/formkit/classes/composite.js'); customElements.define('formkit-composite', FormKitComposite); }); </script>
方式B:添加?client后缀强制客户端加载
给模块路径加上?client后缀,告诉SvelteKit仅在客户端加载该文件:
<script> import { FormKitComposite } from '$components/shared/formkit/classes/composite.js?client'; customElements.define('formkit-composite', FormKitComposite); </script>
2. 在Web Components代码中做环境判断
修改composite.js,仅在浏览器环境下定义类:
// composite.js let FormKitComposite; if (typeof window !== 'undefined' && typeof HTMLElement !== 'undefined') { FormKitComposite = class FormKitComposite extends HTMLElement { // 类的实现代码 }; } export { FormKitComposite };
3. 禁用组件的SSR
如果整个组件都依赖浏览器API,可在组件顶部添加export const ssr = false;,强制组件仅在客户端渲染:
<script> export const ssr = false; import { FormKitComposite } from '$components/shared/formkit/classes/composite.js'; customElements.define('formkit-composite', FormKitComposite); </script>
内容的提问来源于stack exchange,提问作者Snookums
相关产品推荐
相关产品推荐

