React/Node应用中服务器端渲染的外部路由问题



我有一个非常奇怪的问题,如果我运行我的应用程序与客户端渲染然后所有的路由工作完美。然而,当我切换到SSR,然后它运行良好,最初在http://localhost:8001但是当我加载一个新的get请求时,通过在浏览器搜索栏中按enter键来加载一个不同的路由,比如http://localhost:8001/covid然后我得到这个错误…这是用create-react-app

生成的

TypeError [ERR_INVALID_CALLBACK]: Callback必须是一个函数。收到未定义五月回调(fs.js:160:9)在对象。readFile (fs.js 311:14):在D: 回购 WhiteTigerCreateReactApp 服务器/server.js: 37:8在层。handle [as handle_request] (D:RepoWhiteTigerCreateReactAppnode_modulesexpresslibrouterlayer.js:95:5)at next (D:RepoWhiteTigerCreateReactAppnode_modulesexpresslibrouterroute.js:137:13)在路线。调度(D: 回购 WhiteTigerCreateReactApp node_modules lib 路由器 route.js表达:112:3)在层。handle [as handle_request] (D:RepoWhiteTigerCreateReactAppnode_modulesexpresslibrouterlayer.js:95:5)在D: 回购 WhiteTigerCreateReactApp node_modules 表达 lib 路由器 index.js: 281:22(D:RepoWhiteTigerCreateReactAppnode_modulesexpresslibrouterindex.js:354:14)at param (D:RepoWhiteTigerCreateReactAppnode_modulesexpresslibrouterindex.js:365:14)

这是我的nodeJS文件,我加载react应用程序,我已经注释掉了我用于客户端渲染的行

import express from 'express';
import fs from 'fs';
import path from 'path';
import React from 'react';
import ReactDomServer from 'react-dom/server'
import App from '../src/components/App'
const PORT = 8001;
const app = express();
let indexPath = path.join(__dirname, '../build/index.html');
let buildPath = path.join(__dirname, '../build');
app.use(express.static(path.resolve(__dirname, '..', 'build')));
app.get('*', function (req, res) {

console.log("response",indexPath);
//SSR -------------------------
fs.readFile(indexPath), 'utf-8', (err, data) => {
if (err) {
console.log('error from server.js', err);
return res.status(500).send("Some error happened")
}
return res.send(data.replace(
"<div id='root'></div>",
`<div id="root">${ReactDomServer.renderToString(<App />)} </div>`));
}
//Client Render -----------------
//res.sendFile(indexPath);   
});
app.listen(PORT, () => {
console.log(`App launced on ${PORT}`);
});

这是一个单独的服务器文件,这是我正在调用。这将调用上面的代码。

require('ignore-styles')
require('@babel/register')({
ignore: [/(node_module)/],
presets: ['@babel/preset-env', '@babel/preset-react']
})
require('./server')

我的react应用有这个入口点

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from "react-router-dom";
/* ./ means search local file system*/
import './assets/css/styles.css';
import './assets/css/utility.css';
import './assets/css/animate.min.css';
import './assets/css/call-now.css';
import './assets/css/Contact-Form-Clean.css';
import './assets/css/betternav.min.css';
import App from './components/App';
//when importing from a module the file extension is omitted. */
import '../node_modules/font-awesome/css/font-awesome.min.css';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import '../node_modules/bootstrap/dist/js/bootstrap.min.js';
import reportWebVitals from './reportWebVitals';
ReactDOM.hydrate(
<React.StrictMode>
<Router>
<App />
</Router>
</React.StrictMode>,
document.getElementById('root')
);    
reportWebVitals();

我的App组件是这样的,它包含了所有的路由。显然有什么东西在SSR期间不能工作或者不能加载?:/

import { React, Component } from 'react';
import { Switch, Route } from 'react-router-dom'
import '../assets/css/header.css';
import '../assets/css/footer.css';
import Header from './header';
import Footer from './footer';
import Body from './body';
import ClientPage from './clientPage'
import CovidPage from './covidPage'
import Commercial from './commercialPage'
import CarpetFloorPage from './carpetFloor'
import IndustrialConstructionPage from './industrialConstructionPage';
import SafeContractorPage from './safeContractor';
import ContactPage from './contactPage';
import IndustrialCommercialPage from './industrialCommercialPage';
import Popper from 'popper.js';
import BetterNav from '../utility/betternav'
import PageNotFound from './notFoundPage';
class App extends Component { 

componentDidMount()
{
BetterNav();
}
render() {
return (
<div>
<Header></Header>
<Switch>          
<Route exact path='/' component={Body} />          
<Route path='/clients' component={ClientPage} />
<Route path='/covid' component={CovidPage} />
<Route path='/commercial' component={Commercial} />       
<Route path='/carpet-floor' component={CarpetFloorPage} /> 
<Route path='/industrial-construction' component={IndustrialConstructionPage} /> 
<Route path='/safe-contractor' component={SafeContractorPage} />          
<Route path='/contact' component={ContactPage} />
<Route path='/industrial-commercial' component={IndustrialCommercialPage} />                     
<Route component={PageNotFound} />
</Switch>
<Footer></Footer>
</div>
);
}

}
export default App;

自从将server.js中的代码更新为

app.get('*', function (req, res) {

console.log("response",indexPath);
//SSR -------------------------
fs.readFile(indexPath, 'utf-8', (err, data) => {
if (err) {
console.log('error from server.js', err);
return res.status(500).send("Some error happened")
}
return res.send(data.replace(
"<div id='root'></div>",
`<div id="root">${ReactDomServer.renderToString(<App />)} </div>`));
})
//Client Render -----------------
//res.sendFile(indexPath);   
});

应用程序首先加载http://localhost:8001像往常一样没问题。但当我去http://localhost:8001/covid我得到这个错误,而不是…

D: 回购 WhiteTigerCreateReactApp node_modules react-dom cj react-dom-server.node.development.js: 3709把犯错;^

TypeError:无法读取未定义的属性"createElement"at App.render (D:RepoWhiteTigerCreateReactAppsrccomponents/App.js:30:7)(D:RepoWhiteTigerCreateReactAppnode_modulesreact-domcjsreact-dom-server.node.development.js:3450:18)at resolve (D:RepoWhiteTigerCreateReactAppnode_modulesreact-domcjsreact-dom-server.node.development.js:3270:5)在ReactDOMServerRenderer。回购 WhiteTigerCreateReactApp node_modules渲染(D: react-dom cj react-dom-server.node.development.js: 3753:22)在ReactDOMServerRenderer。读(D: 回购 WhiteTigerCreateReactApp node_modules react-dom cj react-dom-server.node.development.js: 3690:29)在对象。回购 WhiteTigerCreateReactApp node_modules renderToString (D: react-dom cj react-dom-server.node.development.js: 4298:27)在D: 回购 WhiteTigerCreateReactApp 服务器/server.js: 27:46在FSReqCallback。readFileAfterClose [as oncomplete] (internal/fs/read_file_context.js:63:3) npm ERR!代码ELIFECYCLE犯错!errno 1 npm ERR!ssr-example@0.1.0 ssr:node server/index.jsnpm犯错!退出状态1 npm ERR!npm犯错!失败了ssr-example@0.1.0 SSR脚本。

我想你的问题在这里:

fs.readFile(indexPath), 'utf-8', (err, data) => {
// ........ (Your code was here)
}

改为:

fs.readFile(indexPath, 'utf-8', (err, data) => {
// ........ (Your code was here)
})

你漏了一个括号。

最新更新