【问题标题】:ReferenceError: document is not defined in Svelte 3ReferenceError:文档未在 Svelte 3 中定义
【发布时间】:2019-10-04 10:25:44
【问题描述】:

我正在尝试在 <script> 中手动 document.createElement 然后在 appendChildaudio 中每次调用 eventListener 来替换它。 在浏览器中一切正常,除了一个页面加载时非常快的错误,但持续时间少于 100 毫秒。终端也有错误

ReferenceError: document is not defined
    at Object (webpack:///./src/components/Record/Component.svelte?:26:17)

似乎在文档尚未准备好时调用了上述内容,但之后就可以了,如何解决?或者在 Svelte 世界 (Sapper) 中销毁和重新创建组件的首选方法是什么?

【问题讨论】:

    标签: svelte


    【解决方案1】:

    感谢Rutuja's answer here,我也能够让我的应用程序正常工作。添加到 Rutuja 的答案中,如果有人在使用 Sapper + Svelte + 另一个包(在我的情况下为 theme.js)时遇到此问题,您可能还需要导入多个组件。这在Mozilla's documentation here for import 中有描述。

    当使用动态导入导入默认导出时,它会起作用 不同。您需要解构并重命名“默认”键 返回的对象。

    (async () => {
      if (somethingIsTrue) {
        const { default: myDefault, foo, bar } = await import('/modules/my-module.js');
      }
    })();
    

    对于我自己的项目(使用theme.js),我必须使用以下逻辑(基于位于heretheme.js 的精简示例):

    const themeState = {
        active: undefined,
        selected: undefined,
        themes: [],
    }
    
    onMount(async () => {
        const { default: Themer, auto, system } = await import('themer.js')
    
        themeState = {
            active: undefined,
            selected: light,
            themes: [light, dark, auto, system],
        }
    
        const themer = new Themer({
            debug: true,
            onUpdate: (theme) => (themeState.active = theme),
            themes: { light, dark, auto, system },
        })
    
        function noThemeSupport({ theme }) {
            return theme === 'system' && !themer.themeSupportCheck()
        }
    
        function setTheme(theme) {
            themeState.selected = theme
            themer.set(theme)
        }
    
        themer.set(themeState.selected)
    })
    

    【讨论】:

      【解决方案2】:

      Sapper 可以很好地与您可能遇到的大多数第三方库配合使用。但是,有时,第三方库的捆绑方式允许它与多个不同的模块加载器一起工作。有时,这段代码会创建对 window 的依赖,例如检查 window.global 是否存在。

      由于像 Sapper 的服务器端环境中没有窗口,简单地导入这样一个模块的动作可能会导致导入失败,并终止 Sapper 的服务器并出现如下错误:

      ReferenceError: 未定义窗口

      解决此问题的方法是从 onMount 函数(仅在客户端调用)中为您的组件使用动态导入,这样您的导入代码就不会在服务器上调用。

      <script>
          import { onMount } from 'svelte';
      
          let MyComponent;
      
          onMount(async () => {
              const module = await import('my-non-ssr-component');
              MyComponent = module.default;
          });
      </script>
      
      <svelte:component this={MyComponent} foo="bar"/>

      【讨论】:

        【解决方案3】:

        document 未在服务器上定义,因此您需要在组件中防范它,以便特定代码仅在浏览器中运行。

        您可以使用onMount 函数,该函数仅在组件渲染后在浏览器中运行。

        <script>
          import { onMount } from 'svelte';
        
          onMount(() => {
            document.createElement(...);
        
            // ...
          });
        </script>
        

        【讨论】:

        • 需要转换心态以记住最初这只是服务器的全部内容。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-10
        • 2021-11-02
        • 2022-01-11
        • 2016-09-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多