如何使用节点 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。