#StackBounty: #javascript #node.js #reactjs #webpack React HMR with SSR

Bounty: 50

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:

enter image description here

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

enter image description here

second call of console.log not logged, even after App.jsx has been changed

enter image description here

What a im doing wrong?


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.