Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gatsby build - Building static HTML for pages failed, error : "WebpackError: ReferenceError: IDBIndex is not defined"

I have a problem while running gatsby build at the Building static html step. I'm working with gatsby for the frontend and firebase for the backend. I have this error :

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

I think the problem comes from my firebase.js file, because when i comment it, the error no longer appears. Here it is :

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

Thanks for yours answers !

like image 340
Sam Mahaux Avatar asked Aug 01 '19 10:08

Sam Mahaux


1 Answers

During SSR "browser globals" like window, document, or IDBIndex are undefined. Only browser runtime can truly understand these, as well as, they can hold state specific to currently running page.

To fix you need to ensure code accessing "globals" is not running during build. If it is third-party lib, you can replace that module with empty module.

Here is simplistic example of using gatsby with firebase auth:

1. Replace firebase module with empty module during SSR.

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

2. Do not use directly firebase code eg. use lazy approach

// 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 }

3. Make sure it is called in browser, eg. useEffect, buttonAction, stateInitialization, customProvider or customHook etc

// 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

There are more approaches to lazy loading like react-loadable, dynamic/lazy imports etc.

See reference Gatsby Docs - Debugging HTML builds.

like image 92
pufface Avatar answered Nov 12 '22 08:11

pufface