gpt4 book ai didi

javascript - 服务器端渲染不渲染UI库

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:38:48 26 4
gpt4 key购买 nike

我正在尝试为我的应用实现服务器端渲染。它曾经是使用 ReactDom 的客户端渲染。在客户端渲染中一切正常,但现在当我将其设为服务器端渲染时,没有渲染任何 CSS 表和 UI 库(Reactstrap + Material UI)。用户界面完全崩溃。

我正在将我的 App.js(包含所有 UI 的实际前端页面)注入(inject)到我的 html.js(模板)中

我的服务器:

import express from 'express';
import React from 'react';
import { renderToString } from 'react-dom/server'
import App from '../../src/App'
import Html from '../../src/html.js'
const app = express();

// console.log that your server is up and running
app.listen(3001, () => console.log(`Listening on port 3001`));

app.get('/',(req,res) => {
const title="2FA SDK"
const body = renderToString(<App/>)
res.send(
Html({
body,
title,
})
)
})

我的 html.js(只是一个简单的模板):

const Html = ({ body, styles, title }) => `
<!DOCTYPE html>
<html>
<head>
<title>${title}</title>
</head>
<body style="margin:0">
<div id="app">${body}</div>
</body>
</html>
`;

我的 app.js(使用 material ui,最小)

render(){
return(
<div className="container">
<div>
<TextField
label="Application Name"
type="text"
variant="outlined"
onChange={this.handleApplicationName}
/>
</div>
<div>
<FormLabel>Phone</FormLabel>
<div>
<OutlinedInput
value={this.state.textmaskArray[2]}
onChange={(e) => this.handlePhoneNumber(e,2)}
labelWidth={200}
/>
</div>
</div>
<Button variant="contained" color="primary" onClick={this.props.buttonAction}>
</Button>
</div>

使用 reactstrap 的 App.js 部分:

render(){
return(
<CardControl
title={"Code Authention"}
message={"For your security, we need to verify your identity by sending a code to your phone number"}
>
<Container>
<Row>
<Col>
<div>{this.props.phoneList}</div>
</Col>
<Col>
<div>{this.props.methodList}</div>
</Col>
</Row>
<Button className="sm-2" disabled={this.props.disabled} color="info" onClick={this.props.buttonAction}>{this.props.buttonName}</Button>
</Container>
</CardControl>

) }我的 webpack.config.js:

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebPackPlugin = require("html-webpack-plugin");
const nodeExternals = require("webpack-node-externals");

module.exports = [
{
/*Config for backend code*/
entry: './src/server/server.js',
target: 'node',
output: {
filename: 'server.js'
},
externals: [nodeExternals()],
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
use: {
loader: "html-loader",
options: { minimize: true }
}
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader,"css-loader"]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./public/index.html",
filename:"./index.html"
}),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename:"[id].css"
})
]
},
]

我正在使用什么:Create-react-app

我尝试过的:我安装了 CSS 加载器,但它根本不起作用。我还查阅了 material-ui 关于服务器端渲染的文档,我觉得我只是遗漏了一小部分,他们提供的说明可能有点矫枉过正。

我需要什么帮助:我想弄清楚为什么来自 material-ui 或 bootstrap 的 UI 组件根本没有得到渲染。我怀疑 nodeExternal 排除了它们,但我不确定。

最佳答案

您需要在客户端对呈现的 HTML 进行合成,以便让 React 接管。

创建一个 client.js 文件:

import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.hydrate(
<App/>,
document.querySelector('#app'),
);

请注意,hydrate 应该与 renderToString 呈现的内容相匹配。

接下来将其添加为您的 webpack 配置中的附加条目:

module.exports = [
{
/*Config for backend code*/
entry: './src/server/server.js',
target: 'node',
output: {
filename: 'server.js'
},
externals: [nodeExternals()],
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
use: {
loader: "html-loader",
options: { minimize: true }
}
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader,"css-loader"]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./public/index.html",
filename:"./index.html"
}),


new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename:"[id].css"
})
]
},
{
entry: './client.js',
output: {
filename: 'bundle.js',
},
module: {
rules: [ {
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
],
},
]

更改您的 html 呈现代码以包含此内容:

const Html = ({ body, styles, title }) => `
<!DOCTYPE html>
<html>
<head>
<title>${title}</title>
</head>
<body style="margin:0">
<div id="app">${body}</div>
<script async src="/bundle.js"></script>
</body>
</html>
`;

我不是 100% 确信这个确切的代码是否有效,但这是一般的想法。

关于javascript - 服务器端渲染不渲染UI库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54221037/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com