我正在尝试创建一个基本的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)
有人能解释一下这里的问题吗?”
1条答案
按热度按时间j91ykkif1#
使用react-router-dom V6,您必须导入像
import { StaticRouter } from "react-router-dom/server
这样的StaticRouter。您还必须删除context=...
这个,在V6中不再可用。