I am trying to setup SSR for React-application, when I am starting server at the first time in development
environment all works good (server sending browser HTML and CSS), after changing source code of my application I getting an error:
This error was throwing because on server source code is outdated, but client has a new version and React notify me over this trouble. I think the solve of this trouble is mechanism called HMR (hot module replacement), but setting up this is hard for me.
My server Webpack-config looks like this:
const serverConfig = merge(commonConfig, {
name: 'server',
target: 'node',
externals: [
nodeExternals({
whitelist: ['webpack/hot/poll?1000'],
}),
],
entry: ['webpack/hot/poll?1000', appServerEntry],
output: {
path: path.resolve(appDist, 'server'),
filename: 'index.js',
},
plugins: [new webpack.HotModuleReplacementPlugin()],
resolve: {
extensions: ['.js', '.jsx', '.json'],
},
});
On each request server render a new version of UI
app.get('*', (request, response) => {
const staticAssets = getStaticAssets();
const routerContext = {};
const renderStream = renderDocumentToStream({
staticAssets,
request,
routerContext,
});
const cacheStream = createCacheStream(request.path);
response.writeHead(200, { 'Content-Type': 'text/html' });
response.write('<!DOCTYPE html>');
cacheStream.pipe(response);
renderStream.pipe(cacheStream);
});
For the hot reload I use webpackDevMiddleware
and webpackHotMiddleware
const webpackInstance = webpack(webpackConfig);
const clientCompiler = webpackInstance.compilers.find(cmpl => cmpl.name === 'client');
app.use(
webpackDevMiddleware(clientCompiler, {
hot: true,
stats: 'errors-only',
}),
);
app.use(webpackHotMiddleware(clientCompiler));
renderDocumentToStream
function intended for render App
to NodeStream
:
import App from './App';
renderDocumentToStream: ({ request, staticAssets, routerContext }) => {
const rootMarkup = renderToString(
<StaticRouter location={request.url} context={routerContext}>
<App />
</StaticRouter>
);
return renderToNodeStream(
<Document
rootMarkup={rootMarkup}
staticAssets={staticAssets}
/>,
);
},
if (module.hot) {
console.log('HERE-0');
module.hot.accept('./App', () => {
console.log('HERE-1');
});
}
When server is starting in stdout
logged first call of console.log
second call of console.log
not logged, even after App.jsx
has been changed
What a im doing wrong?
The warning is clearly indicating that the content is different at client from server. This is not an error but a warning which means, there are going to be performance impact because React has to re-render at client and so the whole purpose of having SSR will be defeated. Please check and make sure that client is also getting the same for hydration as the server. This should fix the issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With