[英]Angular 13 SSR Build Serve eror -- ERROR ReferenceError: document is not defined
[英]React SSR: Document is not defined
我已經為此工作了兩天。 查看了多個堆棧帖子,仍然沒有找到合適的答案。
我正在嘗試在服務器中渲染我的 React 項目,如下所示:
服務器.js
function handleRender(req,res){
const sheetsRegistry = new SheetsRegistry();
const sheetsManager = new Map();
const theme = createMuiTheme({
palette:{
primary:green,
accent: red,
type: 'light',
}
})
const generateClassName = createGenerateClassName();
const html = ReactDOMServer.renderToString(
<JssProvider registry={sheetsRegistry} generateClassName={generateClassName}>
<MuiThemeProvider theme={theme} sheetsManager={sheetsManager}>
<TwoFA />
</MuiThemeProvider>
</JssProvider>
)
const css = sheetsRegistry.toString()
res.send(renderFullPage(html,css))
}
function renderFullPage(html,css){
return `
<!DOCTYPE html>
<html>
<head>
<title>2FA SDK</title>
</head>
<body style="margin:0">
<div id="app">${html}</div>
<script id="jss-server-side">${css}</script>
</body>
</html>
`
}
客戶端.js:
import React from 'react';
import ReactDOM from 'react-dom';
import TwoFA from './App';
import {
MuiThemeProvider,
createMuiTheme,
createGenerateClassName,
} from '@material-ui/core/styles';
import green from '@material-ui/core/colors/green';
import red from '@material-ui/core/colors/red';
class Main extends React.Component{
componentDidMount() {
const jssStyles = document.getElementById('jss-server-side');
if (jssStyles && jssStyles.parentNode) {
jssStyles.parentNode.removeChild(jssStyles);
}
}
render(){
return <TwoFA />
}
}
const theme = createMuiTheme({
palette: {
primary: green,
accent: red,
type: 'light',
},
});
const generateClassName = createGenerateClassName();
if (typeof window !== 'undefined'){
ReactDOM.hydrate(
<JssProvider generateClassName={generateClassName}>
<MuiThemeProvider theme={theme}>
<TwoFA/>
</MuiThemeProvider>
</JssProvider>,
document.querySelector('#app'),
);
}
Webpack.config.js
module.exports = [
{
/*Config for backend code*/
entry: './src/server/server.js',
output: {
filename: 'server.js'
},
externals: [nodeExternals()],
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
use: {
loader: "html-loader",
options: { minimize: true }
}
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader,"css-loader"]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./public/index.html",
filename:"./index.html"
}),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename:"[id].css"
})
]
},
{
entry: './src/client.js',
output: {
filename: 'bundle.js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
{
test: /\.html$/,
use: {
loader: "html-loader",
options: { minimize: true }
}
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader,"css-loader"]
}
],
},
plugins: [
new HtmlWebPackPlugin({
template: "./public/index.html",
filename:"./index.html"
}),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename:"[id].css"
})
]
}
]
我嘗試過的:我在 SO 上搜索,發現許多帖子建議進行條件檢查,如下所示: if (typeof window !== 'undefined')
。 但是,這並不能解決問題。
我也了解到這個錯誤是因為在SSR期間,服務器端沒有文檔項目。
我在 github 問題頁面上搜索過,有人提到他遇到了 webpack 的問題,但同一個項目在 browserify 上運行良好。
我需要什么幫助:我正在嘗試解決這個問題,因為它會導致應用程序崩潰。
我懷疑 webpack 有問題。 我正在尋找解決此問題的方法
這個問題通常發生是因為在服務器上呈現 react 時。 它在服務器端沒有文檔或窗口對象,這些對象僅在瀏覽器上可用。
嘗試在componentDidMount
中或之后調用文檔函數。
componentDidMount(){
this.setState({documentLoaded:true});
}
someFunction(){
const { documentLoaded } = this.state;
if(documentLoaded){
// LOGIC USING DOCUMENT OBJECT
}
}
如果您使用的是 react-hooks,則可以創建自定義 useDocument 掛鈎:
import React, { useEffect, useState } from 'react'
export const useDocument = () => {
const [myDocument, setMyDocument] = useState(null)
useEffect(() => {
setMyDocument(document)
}, [])
return myDocument
}
在您的組件中:
...
const doc = useDocument()
...
<SomeComponent
ref={doc && doc.body}
...
/>
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.