Gatsby / webpack-未定义WebpackError窗口-在哪里?

时间:2020-08-06 13:11:05

标签: webpack gatsby

运行gatsby build时,出现以下错误。

我知道如何修复它(例如,检查窗口的typedef),但找不到该窗口的用法吗?我怎么知道在哪里?我怀疑是一个节点模块,因为我自己的代码中没有太多的窗口引用

非常感谢

failed Building static HTML for pages - 10.845s

 ERROR #95312 

"window" is not available during server side rendering.

See our docs page for more info on this error: https://gatsby.dev/debug-html





  WebpackError: ReferenceError: window is not defined
  
  - build-html.js:110 doBuildPages
    /[gatsby]/dist/commands/build-html.js:110:24
  
  - build-html.js:124 async buildHTML
    /[gatsby]/dist/commands/build-html.js:124:3
  
  - build.js:206 async build
    /[gatsby]/dist/commands/build.js:206:5

4 个答案:

答案 0 :(得分:2)

一次删除一个第三方节点包,以找到有问题的模块。然后,您将需要派生该程序包并对其进行修复,以使其不使用window对象,或者查找替代程序包。

答案 1 :(得分:1)

也许设置globalObject会有所帮助。

<ScrollViewer HorizontalScrollBarVisibility="Disabled"
              VerticalScrollBarVisibility="{Binding IsScrollEnabled, Converter={StaticResource BoolToVisibilityConverter}}"
              PreviewMouseWheel="UIElement_OnPreviewMouseWheel">
   <ItemsPresenter />
</ScrollViewer>

globalObject的默认值为private void UIElement_OnPreviewMouseWheel(object sender, MouseWheelEventArgs e) { e.Handled = true; }

答案 2 :(得分:1)

如您所说,如果您未在代码中使用window(解决方法是检查是否使用typeof进行了定义),则问题出在您的第三方依赖项之一正在将window用作自己代码中的全局对象。

您必须找到哪一个,并在您的webpack配置中添加一个null加载程序。在您的gatsby-node.js中:

exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
  if (stage === "build-html") {
    actions.setWebpackConfig({
      module: {
        rules: [
          {
            test: /bad-module/,
            use: loaders.null(),
          },
        ],
      },
    })
  }
}

在上面的代码中,/bad-module/node_modules中要避免转换的依赖项。基本上,在服务器渲染期间,您要用虚拟模块替换有问题的模块。

答案 3 :(得分:1)

感谢所有其他答案

我尝试了@Raz Ronen的答案,但是更改globalObject导致了其他问题,例如未定义的localStorage。

我尝试删除所有节点模块,但没有帮助。

奇怪的是,在删除节点模块之后,错误发生了变化,我可以看到这一行!错误。这是盖茨比自己的“导航”方法。

我的应用程序中有类似于in the docs的私有路线:

mport React from "react"
import { navigate } from "gatsby"
import { isLoggedIn } from "../services/auth"

const PrivateRoute = ({ component: Component, location, ...rest }) => {
  if (!isLoggedIn() && location.pathname !== `/app/login`) {
    navigate("/app/login")
    return null
  }

  return <Component {...rest} />
}

export default PrivateRoute

但是,我不得不将导航置于useEffect钩子内,以解决如下问题:

const PrivateRoute = ({ component: Component, location, ...rest }) => {
  const user = useContext(AuthenticationContext)
  useEffect(() => {
    checkLoginStatus()
  }, [])

  const checkLoginStatus = () => {
    if (!user && location.pathname !== `/login`) {
      navigate("/login")
    }
  }

  return <Component {...rest} />
}