在构建静态html步骤中运行gatsby build
时遇到问题。我正在为前端使用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
我认为问题来自我的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
感谢您的回答!
答案 0 :(得分:0)
在SSR期间,未定义window
,document
或IDBIndex
之类的“浏览器全局变量”。只有浏览器运行时才能真正理解这些内容,并且它们可以保持特定于当前正在运行的页面的状态。
要解决此问题,您需要确保在构建过程中未运行访问“全局变量”的代码。如果它是第三方库,则可以将该模块替换为空模块。
这是将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(),
},
],
},
})
}
}
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 }
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
还有更多的延迟加载方法,例如react-loadable,动态/延迟导入等。
答案 1 :(得分:0)
如前所述,在构建期间无法使用浏览器全局变量。
在声明window
对我有用之前,只需检查firebase
:
let firebase;
if (typeof window !== 'undefined') {
firebase = require('firebase');
}
编辑:不完全(在某些情况下可以工作,但是一旦我的应用程序变得更复杂,它就会失败)
我建议关注这篇文章:Firebase and Gatsby, Together At Last。