Pav*_*vel 12 javascript express reactjs webpack webpack-dev-server
我试图用服务器端渲染构建ReactJs应用程序我的客户端和服务器的入口点:
const store = createStore(window.__INITIAL_STATE__);
hydrate(
<Provider store={store}>
<BrowserRouter>{renderRoutes(routes)}</BrowserRouter>
</Provider>,
document.querySelector('#root')
);
Run Code Online (Sandbox Code Playgroud)
const app = express();
if (isDev) {
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const config = require('../../webpack.config.js');
const compiler = webpack(config);
app.use(express.static('/public'));
app.use(
webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath,
stats: 'errors-only',
})
);
}
app.get('*', (req, res) => {
const helmet = Helmet.renderStatic();
const htmlAttrs = helmet.htmlAttributes.toComponent();
const bodyAttrs = helmet.bodyAttributes.toComponent();
const context = {};
const data = {};
res.set('content-type', 'text/html');
res.send(
'<!DOCTYPE html>' +
renderToString(
<html {...htmlAttrs}>
<head>
{helmet.title.toComponent()}
{helmet.meta.toComponent()}
{helmet.link.toComponent()}
</head>
<body {...bodyAttrs}>
<div id="root">
<StaticRouter location={req.url} context={context}>
{renderRoutes(routes)}
</StaticRouter>
</div>
<script
dangerouslySetInnerHTML={{
__html: `window.__INITIAL_STATE__ = ${JSON.stringify(data)}`,
}}
/>
<script src="/public/vendor.js" />
<script src="/public/app.js" />
</body>
</html>
)
);
});
Run Code Online (Sandbox Code Playgroud)
和组件:
home.jsx
import React, { Component } from 'react';
class Home extends Component {
render() {
return <div>home</div>;
}
}
export default Home;
Run Code Online (Sandbox Code Playgroud)
当我更改我的组件Home并刷新浏览器页面时,我收到此错误:
警告:文本内容不匹配.服务器:"home"客户端:"home1"
它确定,因为服务器渲染旧版本的代码.如何在服务器上重新加载代码以使客户端和服务器版本相同?
对于那些因为您的客户端和服务器故意呈现不同内容而发现此错误的人(例如服务器呈现深色主题,该主题在加载时被用户首选项替换),请使用suppressHydrationWarning抑制错误。
例如:
<div suppressHydrationWarning>Ignore this</div>
Run Code Online (Sandbox Code Playgroud)
这里的问题是您的服务器端应用程序不反映代码更改。为此,您必须将 Express 应用程序配置为 Webpack 条目。
简而言之,您需要 2 个 webpack 配置,一个用于服务器,另一个用于客户端代码。服务器看起来像这样
module.exports = {
entry: {
server: './server.js',
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].js'
},
target: 'node',
node: {
// Need this when working with express, otherwise the build fails
__dirname: false, // if you don't put this is, __dirname
__filename: false, // and __filename return blank or /
},
externals: [nodeExternals()], // Need this to avoid error when working with Express
module: {
rules: [
{
// Transpiles ES6-8 into ES5
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
// Loads the javacript into html template provided.
// Entry point is set below in HtmlWebPackPlugin in Plugins
test: /\.html$/,
use: [{loader: "html-loader"}]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./index.html",
filename: "./index.html",
excludeChunks: [ 'server' ]
})
]
}
Run Code Online (Sandbox Code Playgroud)
这是一篇很好的文章,详细解释了如何做到这一点
| 归档时间: |
|
| 查看次数: |
6172 次 |
| 最近记录: |