0

I've been doing a lot of reading on this, it seems that a lot of boilerplates available on github that enable both of these use webpack-dev-server to rebuild the client bundle. However, I'm not sure how or if the server is hot-module reloaded. Is there a way to configure webpack to enable HMR on the server-side? Otherwise, it seems that anything I change won't be rendered by the server, only refreshed on the client.

My webpack config looks something like this:

module.exports = {
  entry: "./js/client.js",
  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        exclude: /(node_modules|bower_components)/,
        loader: 'babel-loader',
        query: {
          presets: ['react', 'es2015', 'stage-0'],
          plugins: ['react-html-attrs', 'transform-class-properties', 'transform-decorators-legacy'],
        }
      }
    ]
  },
  output: {
    path: __dirname + "/public/",
    filename: "client.min.js"
  }
};

server.js:

app.get('/', function(request, response) {
  var html = ReactDOMServer.renderToString(React.createElement(Component));
  response.send(html);
});

Component.js:

module.exports = React.createClass({
  _handleClick: function() {
    alert();
  },

  render: function() {
    return (
      <html>
        <head>
          <title>{this.props.title}</title>
          <link rel="stylesheet" href="/style.css" />
        </head>
        <body>
          <h1>{this.props.title}</h1>
          <p>isn't server-side rendering remarkable?</p>
          <button onClick={this._handleClick}>Click me</button>
          <script dangerouslySetInnerHTML={{
            __html: 'window.PROPS=' + JSON.stringify(this.props)
          }} />
          <script src="/client.min.js" />
        </body>
      </html>
    );
  }
})

and client.js:

var props = window.PROPS;

ReactDOM.render(React.createElement(Component, props), document);

I use webpack-dev-server --content-base src --inline --hot to run webpack

user490895
  • 335
  • 2
  • 7
  • 17

1 Answers1

1

You're going to want to run your code via your server.js. Create a script in your package.json to run that file.

For example:

"serve":"nodemon server.js"

Then, add an alternative to webpack-dev-server which is the webpack-dev-middleware and webpack-hot-middlware which can help you with HMR.

This is how you're server.js will look like:

import express from 'express';
import webpack from 'webpack';
import path from 'path';
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';

const port = 5000;
const app = express();
const config = require(path.resolve("./webpack.config.js"));

const compiler = webpack(config);

app.use(webpackDevMiddleware(compiler, {
  noInfo: true,
  publicPath: config.output.publicPath,
}));

app.use(webpackHotMiddleware(compiler));

app.get("*", function(req, res, next) {
    res.sendFile( path.join( __dirname, '/path/to/your/index.html') );
});

app.listen(port, function(err) {
    if(err) {
        return console.log(err);
    }
    return console.log(`App is now running on http://localhost:${port}`);
});

Then, run your script, like so:

npm run serve

And just visit the port on the browser, your client will then show up.

Hope this helps.

ickyrr
  • 1,963
  • 1
  • 14
  • 14
  • Ok I did that, but what happens is that the server.js itself isn't hot reloaded. I'm guessing it's because it isn't a dependency of my client. Would I need to add a sever entry point to my webpack config? – user490895 Feb 09 '17 at 17:45
  • no, you don't need to do that. Have you installed and/or run `nodemon`? – ickyrr Feb 10 '17 at 03:03
  • `nodemon`'s purpose is to watch your `server.js`'s changes. – ickyrr Feb 10 '17 at 03:11