NodeJS ReactJS:错误:元素类型无效:运行SSR应用程序时需要字符串

tuwxkamq  于 2023-04-20  发布在  Node.js
关注(0)|答案(1)|浏览(122)

我正在尝试创建一个基本的SSR react应用程序。以下是我遵循的步骤的完整列表:

使用create-react-app工具创建一个新的React app:

npx create-react-app my-ssr-app

安装必要的依赖:

cd my-ssr-app
npm install --save express react react-dom react-router-dom react-helmet
npm install --save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader css-loader style-loader webpack webpack-cli webpack-node-externals

在应用根目录下创建server.js文件:

const path = require('path');
const express = require('express');
const React = require('react');
const ReactDOMServer = require('react-dom/server');
const { StaticRouter } = require('react-router-dom');
const { Helmet } = require('react-helmet');
const App = require('./src/App').default;

const PORT = process.env.PORT || 3000;
const app = express();

app.use(express.static(path.join(__dirname, 'build')));

app.get('*', (req, res) => {
  const context = {};
  const appMarkup = ReactDOMServer.renderToString(
    <StaticRouter location={req.url} context={context}>
      <App />
    </StaticRouter>
  );
  const helmet = Helmet.renderStatic();

  res.status(200).send(`
    <!DOCTYPE html>
    <html>
      <head>
        ${helmet.title.toString()}
        ${helmet.meta.toString()}
        <link rel="stylesheet" href="/static/css/main.css">
      </head>
      <body>
        <div id="root">${appMarkup}</div>
        <script src="/static/js/main.js"></script>
      </body>
    </html>
  `);
});

app.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`);
});

修改package.json文件,添加新的build命令:

{
  "scripts": {
    "build": "react-scripts build && webpack --config webpack.server.js"
  }
}

在应用根目录下创建webpack.server.js文件:

const path = require('path');
const nodeExternals = require('webpack-node-externals');

module.exports = {
  mode: 'production',
  entry: './server.js',
  output: {
    path: path.join(__dirname, 'build'),
    filename: 'server.js',
    libraryTarget: 'commonjs2',
  },
  target: 'node',
  externals: [nodeExternals()],
  module: {
    rules: [
      {
        test: /\.(js|mjs|jsx|ts|tsx)$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          presets: [
            '@babel/preset-env',
            '@babel/preset-react',
          ],
        },
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
  resolve: {
    extensions: ['.js', '.jsx', '.json'],
  },
};

运行build命令:

npm run build

启动服务器:

node build/server.js

然而,在http://localhost:3000上运行应用程序后,我得到以下错误:

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
    at renderElement (/Users/mmt10470/Documents/dev_per/my-ssr-app/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js:6047:9)
    at renderNodeDestructiveImpl (/Users/mmt10470/Documents/dev_per/my-ssr-app/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js:6108:11)
    at renderNodeDestructive (/Users/mmt10470/Documents/dev_per/my-ssr-app/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js:6080:14)
    at retryTask (/Users/mmt10470/Documents/dev_per/my-ssr-app/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js:6532:5)
    at performWork (/Users/mmt10470/Documents/dev_per/my-ssr-app/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js:6580:7)
    at /Users/mmt10470/Documents/dev_per/my-ssr-app/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js:6904:12
    at scheduleWork (/Users/mmt10470/Documents/dev_per/my-ssr-app/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js:78:3)
    at startWork (/Users/mmt10470/Documents/dev_per/my-ssr-app/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js:6903:3)
    at renderToStringImpl (/Users/mmt10470/Documents/dev_per/my-ssr-app/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js:6977:3)
    at Object.renderToString (/Users/mmt10470/Documents/dev_per/my-ssr-app/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js:7065:10)

有人能解释一下这里的问题吗?”

j91ykkif

j91ykkif1#

使用react-router-dom V6,您必须导入像import { StaticRouter } from "react-router-dom/server这样的StaticRouter。您还必须删除context=...这个,在V6中不再可用。

相关问题