gatsby build - 为页面构建静态 HTML 失败,错误:“WebpackError: ReferenceError: IDBIndex is not defined”

Sam*_*aux 6 firebase gatsby

gatsby buildBuilding static html step 中运行时遇到问题。我在前端使用 gatsby,后端使用 firebase。我有这个错误:

ERROR #95313 

Building static HTML failed

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


 85 | ]);
 86 | 
>    87 | proxyRequestMethods(Index, '_index', IDBIndex, [
    | ^
 88 |   'get',
 89 |   'getKey',
 90 |   'getAll',


 WebpackError: ReferenceError: IDBIndex is not defined
Run Code Online (Sandbox Code Playgroud)

我认为问题来自我的 firebase.js 文件,因为当我评论它时,错误不再出现。这里是 :

import firebase from "firebase"

const firebaseConfig = {
  apiKey: "AIzaSyDCiX9_kFYoatKJB7Idc-K_k2XrkwUs5So",
  authDomain: "gourmeto-6fd67.firebaseapp.com",
  databaseURL: "https://gourmeto-6fd67.firebaseio.com",
  projectId: "gourmeto-6fd67",
  storageBucket: "gourmeto-6fd67.appspot.com",
  messagingSenderId: "208164789511",
  appId: "1:208164789511:web:22745f19a559f32a"
};


  firebase.initializeApp(firebaseConfig)

  /*export const googleProvider = new firebase.auth.GoogleAuthProvider()
  export const facebookProvider = new firebase.auth.FacebookAuthProvider()
  export const auth = firebase.auth()*/


  /*export const signOut = () => {
    firebase.auth().signOut()
  }*/

  export default firebase
Run Code Online (Sandbox Code Playgroud)

感谢您的回答!

小智 1

在 SSR 期间,“浏览器全局变量”如windowdocumentIDBIndex未定义。只有浏览器运行时才能真正理解这些,并且它们可以保存特定于当前运行页面的状态。

要修复此问题,您需要确保访问“全局变量”的代码在构建期间未运行。如果是第三方库,可以用空模块替换该模块。

这是使用 gatsby 和 firebase auth 的简单示例:

1. 在 SSR 期间将 firebase 模块替换为空模块。

// gatsby-node.js
exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
  if (stage === "build-html") {
    actions.setWebpackConfig({
      module: {
        rules: [
          {
            test: /@firebase/,
            use: loaders.null(),
          },
        ],
      },
    })
  }
}
Run Code Online (Sandbox Code Playgroud)

2.不要直接使用firebase代码,例如。使用惰性方法

// firebase-wrapper.js
import firebase from 'firebase'

const firebaseConfig = {...}

const lazy = (fn) => {
  let isLoaded = false
  let result
  return () => {
    if (!isLoaded) {
      isLoaded = true
      result = fn()
    }
    return result
  }
}

const app = lazy(() => firebase.initializeApp(firebaseConfig))
const auth = lazy(() => app().auth())
const GoogleAuthProvider = lazy(() => new firebase.auth.GoogleAuthProvider())

export { app, auth, GoogleAuthProvider }
Run Code Online (Sandbox Code Playgroud)

3. 确保在浏览器中调用它,例如。useEffect、buttonAction、stateInitialization、customProvider 或 customHook 等

// index.js
import React, {useState, useEffect} from "react"
import {auth, GoogleAuthProvider} from "../firebase-wrapper.js"

const App = () => {
  const [user, setUser] = useState(null)
  useEffect(()=>{
    return auth().onAuthStateChanged(setUser)
  })
  return (
    <div>
      <div>User:{user && user.uid}</div>
      <button onClick={()=>auth().signInWithPopup(GoogleAuthProvider())}>Sing in with Google</button>
      <button onClick={()=>auth().signOut()}>Sign out</button>
   </div>
  )
}

export default App
Run Code Online (Sandbox Code Playgroud)

还有更多延迟加载的方法,如反应加载、动态/延迟导入等。

请参阅参考Gatsby 文档 - 调试 HTML 构建