如何使用节点 reactjs 进行服务器端渲染?
How to do server side rendering with node reactjs?
我在 reactjs 中创建了一个示例项目并使用 node 作为后端。我已经用 webpack 构建了反应项目。现在我想从服务器端呈现我的 React 应用程序,但遇到错误:
const express = require('express');
const path = require('path');
const logger = require('morgan');
const bodyParser = require('body-parser');
const cors = require('cors');
const { renderToString } = require("react-dom/server");
const { StaticRouter } = require("react-router-dom")
const React = require("react");
const App = require('./src/App')
const session = require('express-session');
const routes = require('./server/index');
const port = process.env.PORT || 3000;
const app = express();
app.use(express.static(path.join(__dirname, 'dist')));
app.use(cors());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
//app.use(cookieParser());
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', '*');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET,POST');
// Request headers you wish to allow
res.setHeader(
'Access-Control-Allow-Headers',
'X-Requested-With,content-type',
);
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
// end
app.use('/', routes);
app.use((req, res, next) => {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
if (app.get('env') === 'development') {
app.use((err, req, res, next) => {
res.status(err.status || 500);
res.json({
message: err.message,
error: err,
});
});
}
app.use((err, req, res, next) => {
res.status(err.status || 500);
res.json({
message: err.message,
error: {},
});
});
router.get("*", (req, res) => {
// Render the component to a string.
const html = ReactDOMServer.renderToString(
<StaticRouter location={req.url} context={context}>
<App />
</StaticRouter>
);
const finalDocument =`<html>
<head>
<title>Your App Title</title>
</head>
<body>
<div id="root">${html}</div>
</body>
</html>
`;
res.send(finalDocument);
});
app.listen(port, () => {
console.log('Api Server running on port' + port);
});
module.exports = app;
package.json
{
"name": "ssrnodereact",
"version": "0.1.0",
"private": true,
"dependencies": {
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.11.2",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^11.2.7",
"@testing-library/user-event": "^12.8.3",
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"cryptr": "^6.0.2",
"dotenv": "^10.0.0",
"express": "^4.17.1",
"express-session": "^1.17.2",
"formik": "^2.2.9",
"helmet": "^4.6.0",
"morgan": "^1.10.0",
"nodemailer": "^6.6.3",
"path": "^0.12.7",
"pg": "^8.7.1",
"prettier": "^2.3.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-ga": "^3.3.0",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"typescript": "^4.3.5",
"web-vitals": "^1.1.2",
"yup": "^0.32.9"
},
"scripts": {
"build": "webpack --mode production",
"start": "npm run build && nodemon server.js",
"test": "react-scripts test",
"eject": "react-scripts eject",
"format": "prettier --write ./**/*.{js,jsx,ts,tsx,css,md,json,html} --config ./.prettierrc"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@babel/core": "^7.15.0",
"@babel/preset-env": "^7.15.0",
"@babel/preset-react": "^7.14.5",
"babel-loader": "^8.2.2",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^3.2.0",
"react-hot-loader": "^4.13.0",
"ts-loader": "^8.3.0",
"webpack": "^4.44.0",
"webpack-cli": "^4.7.2",
"webpack-dev-server": "^3.11.2"
}
}
Got following error:
error
我已经尝试了以下解决方案,但未能解决错误:
我不确定 React 是否是适合您需求的框架。使用像 NextJS 这样的框架可以更轻松、更高效地完成服务器端渲染。
你可以查看this plugin,里面有例子让你轻松做SSR。
我在 reactjs 中创建了一个示例项目并使用 node 作为后端。我已经用 webpack 构建了反应项目。现在我想从服务器端呈现我的 React 应用程序,但遇到错误:
const express = require('express');
const path = require('path');
const logger = require('morgan');
const bodyParser = require('body-parser');
const cors = require('cors');
const { renderToString } = require("react-dom/server");
const { StaticRouter } = require("react-router-dom")
const React = require("react");
const App = require('./src/App')
const session = require('express-session');
const routes = require('./server/index');
const port = process.env.PORT || 3000;
const app = express();
app.use(express.static(path.join(__dirname, 'dist')));
app.use(cors());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
//app.use(cookieParser());
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', '*');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET,POST');
// Request headers you wish to allow
res.setHeader(
'Access-Control-Allow-Headers',
'X-Requested-With,content-type',
);
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
// end
app.use('/', routes);
app.use((req, res, next) => {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
if (app.get('env') === 'development') {
app.use((err, req, res, next) => {
res.status(err.status || 500);
res.json({
message: err.message,
error: err,
});
});
}
app.use((err, req, res, next) => {
res.status(err.status || 500);
res.json({
message: err.message,
error: {},
});
});
router.get("*", (req, res) => {
// Render the component to a string.
const html = ReactDOMServer.renderToString(
<StaticRouter location={req.url} context={context}>
<App />
</StaticRouter>
);
const finalDocument =`<html>
<head>
<title>Your App Title</title>
</head>
<body>
<div id="root">${html}</div>
</body>
</html>
`;
res.send(finalDocument);
});
app.listen(port, () => {
console.log('Api Server running on port' + port);
});
module.exports = app;
package.json
{
"name": "ssrnodereact",
"version": "0.1.0",
"private": true,
"dependencies": {
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.11.2",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^11.2.7",
"@testing-library/user-event": "^12.8.3",
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"cryptr": "^6.0.2",
"dotenv": "^10.0.0",
"express": "^4.17.1",
"express-session": "^1.17.2",
"formik": "^2.2.9",
"helmet": "^4.6.0",
"morgan": "^1.10.0",
"nodemailer": "^6.6.3",
"path": "^0.12.7",
"pg": "^8.7.1",
"prettier": "^2.3.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-ga": "^3.3.0",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"typescript": "^4.3.5",
"web-vitals": "^1.1.2",
"yup": "^0.32.9"
},
"scripts": {
"build": "webpack --mode production",
"start": "npm run build && nodemon server.js",
"test": "react-scripts test",
"eject": "react-scripts eject",
"format": "prettier --write ./**/*.{js,jsx,ts,tsx,css,md,json,html} --config ./.prettierrc"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@babel/core": "^7.15.0",
"@babel/preset-env": "^7.15.0",
"@babel/preset-react": "^7.14.5",
"babel-loader": "^8.2.2",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^3.2.0",
"react-hot-loader": "^4.13.0",
"ts-loader": "^8.3.0",
"webpack": "^4.44.0",
"webpack-cli": "^4.7.2",
"webpack-dev-server": "^3.11.2"
}
}
Got following error:
error
我已经尝试了以下解决方案,但未能解决错误:
我不确定 React 是否是适合您需求的框架。使用像 NextJS 这样的框架可以更轻松、更高效地完成服务器端渲染。
你可以查看this plugin,里面有例子让你轻松做SSR。