【问题标题】:WebpackError: ReferenceError: document is not defined - netlify buildWebpackError:ReferenceError:文档未定义 - netlify 构建
【发布时间】:2021-03-12 15:35:32
【问题描述】:

我在 netlify 上构建项目时遇到错误(WebpackError: ReferenceError: document is not defined)。在开发中工作正常!

我看到可以用 JSDOM 解决这个问题,但我已经尝试过,但我无法做到。

    import React from "react";
    import "../css/DarkMode.css";
    
    const DarkMode = () => {
      let clickedClass = "clicked";
      const body = document.body;
      const lightTheme = "light";
      const darkTheme = "dark";
      let theme;
    
      if (localStorage) {
        theme = localStorage.getItem("theme");
      }
    
      if (theme === lightTheme || theme === darkTheme) {
        body.classList.add(theme);
      } else {
        body.classList.add(lightTheme);
      }
    
      const switchTheme = (e) => {
        if (theme === darkTheme) {
          body.classList.replace(darkTheme, lightTheme);
          e.target.classList.remove(clickedClass);
          localStorage.setItem("theme", "light");
          theme = lightTheme;
        } else {
          body.classList.replace(lightTheme, darkTheme);
          e.target.classList.add(clickedClass);
          localStorage.setItem("theme", "dark");
          theme = darkTheme;
        }
      };
    
      return (
        <button
          className={theme === "dark" ? clickedClass : ""}
          id="darkMode"
          className={"btnDarkMode"}
          onClick={(e) => switchTheme(e)}
        ></button>
      );
    };
    
    export default DarkMode;

【问题讨论】:

    标签: reactjs build gatsby


    【解决方案1】:

    扩展@mirik999's answer:

    这与jsdom本身无关。如前所述,使用 React,您正在创建和操作一个虚拟 DOM(vDOM),而使用您的 sn-p,您直接指向真实的 DOM(document.body 等等)。此外,这些操作大大降低了代码/应用程序的性能,因为它们对浏览器造成了巨大的成本,这就是 React 如此快速的原因(除其他外)。

    在 React 应用程序中操作真实 DOM 可能会导致严重的警告和警告,可能会阻塞 hydration of React(按需刷新/重新渲染新内容)。

    总而言之,您的代码在gatsby develop 下而不是gatsby build 下工作的事实是,因为gatsby develop 是由浏览器处理的,where there are global objects (such as window or document)gatsby build id 在 Node 服务器中编译,显然没有 windowdocument 因为它们甚至还没有创建。

    简单的解决方法是在这种情况下包装您的代码(您使用全局对象的地方):

    if (typeof window !== `undefined`) { // or typeof document !== 'undefined'
      // your code that uses global objects here
    }
    

    但正如我所说,它可能会阻止 React 的水合作用。

    要在 Gatsby 中添加主题,您有很多选择,例如使用插件 (gatsby-plugin-dark-mode) 或使用基于 React 的方法。

    有用的资源:

    【讨论】:

    • 谢谢你!我已经尝试过使用 gatsby-plugin-dark-mode,但它有一个我不喜欢的功能,如果你的 bowser 默认设置了暗模式,它会自动将页面更改为暗模式,我不喜欢我想要的一个按钮来打开和关闭,但谢谢。我肯定会尝试基于 React 的方法。谢谢人
    【解决方案2】:

    你想实现主题切换完全错误。

    1. React 使用虚拟 DOM 而不是真实 DOM。 (虚拟 DOM 是 HTML 树的对象版本) 这就是为什么在页面初始化之前没有定义文档的原因。如果您想获取文档,最好在 useEffect() 挂钩中使用它。 (页面初始化后)
    2. 在你的情况下,你有很多选择来实现多主题,我建议使用 styled-components

    【讨论】:

      猜你喜欢
      • 2020-01-06
      • 1970-01-01
      • 2019-11-07
      • 1970-01-01
      • 2021-12-18
      • 1970-01-01
      • 2022-01-06
      • 2016-05-06
      • 2020-10-26
      相关资源
      最近更新 更多