SvelteKit控制台错误:“导入库时未定义窗口”

14

我想要导入使用“window”属性的apexChart库,但在控制台中出现了错误。

[vite] Error when evaluating SSR module /src/routes/prehled.svelte:
ReferenceError: window is not defined

我尝试在挂载后使用 ApexCharts,但错误仍未消失。

<script>
 import ApexCharts from 'apexcharts'
 import { onMount } from 'svelte'
 const myOptions = {...myOptions}
 onMount(() => {
   const chart = new ApexCharts(document.querySelector('[data-chart="profit"]'), myOptions)
   chart.render()
 })
</script>

我尝试在确定浏览器存在时导入一个 ApexCharts。

 import { browser } from '$app/env'
 if (browser) {
   import ApexCharts from 'apexcharts'
 }

但我得到了错误信息 "'import' 和 'export' 只能出现在顶层"

我尝试在 svelte.config.js 中禁用 SSR

import adapter from '@sveltejs/adapter-static';
const config = {
    kit: {
        adapter: adapter(),
    prerender: {
      enabled: false
    },
    ssr: false,
}

我尝试创建一个组件,在其中导入apexChart库,并创建了一个条件,仅在存在浏览器时使用此组件

{ #if browser }
  <ProfitChart />
{ /if }

没有什么能帮助我。

有人知道如何帮助我吗?

3个回答

12

最简单的方法是将apexcharts作为独立库包含在您的网页中,像这样:

<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>

然后只需在onMount中使用它:

onMount(() => {
  const chart = new ApexCharts(container, options)
  chart.render()
})

你可以在你的app.html文件中添加这行代码,或者在需要的地方使用<svelte:head>块进行包含。

另一种方法是在onMount生命周期期间动态导入。

onMount(async () => {
  const ApexCharts = (await import('apexcharts')).default
  const chart = new ApexCharts(container, options)
  chart.render()
})

额外的提示:使用bind:this代替document.querySelector来获取DOM元素,这是更符合"Svelte"的方式。


动态导入完美运行。 - Eric
1
dynamic 导入修复了我的 window not defined 错误。谢谢! - Clément Péau

6

我发现使用Vite插件的最后一个选项最终代码较少,但会失去VSCode中的Intellisense功能,并且import将被标记为错误(在末尾有临时解决方法):

https://kit.svelte.dev/faq#how-do-i-use-x-with-sveltekit-how-do-i-use-a-client-side-only-library-that-depends-on-document-or-window
  1. 安装vite插件:npm i -D vite-plugin-iso-import
  2. 将插件添加到svelte.config.js中:
       kit: {
          vite: {
            plugins: [
                isoImport(),
            ],
  1. 将插件添加到 TypeScript 配置中(如果你使用 TS):
"compilerOptions": {
    "plugins": [{ "name": "vite-plugin-iso-import" }],
  • 像往常一样使用,但注意导入时的"?client":
  • <script context="module">
        import { chart } from 'svelte-apexcharts?client';
        import { onMount } from 'svelte'
        let myOptions = {...myOptions}
        onMount(() => {
            myOptions = {...updated options/data}
        });
    </script>
    
    <div use:chart={myOptions} />
    

    调试提示: 为了让导入不会被暂时标记为错误,请执行以下操作:

    1. npm run dev命令编译你的项目,然后在浏览器中测试至少一次。
    2. 现在删除?client,保存并像往常一样进行调试。

    vite-plugin-iso-import 文档 https://github.com/bluwy/vite-plugin-iso-import - Mikko Ohtamaa

    0

    对于所有尝试在js或ts文件中动态导入的人,请尝试以下方法:

    在任何Svelte组件的挂载期间导入您的包。

    onMount(async () => {
     const Example = await import('@creator/examplePackage');
     usePackageInJSOrTS(Example.default);
    });
    

    在你的js/ts函数中使用导入的包。你需要传递构造函数的默认值。

    export function usePackageInJsOrTs(NeededPackage) { 
        let neededPacakge = new NeededPackage();
    }
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接