title: Hot reloading in a React app with express server
body: <p>As of now I have a boilerplate set up for a MERN application having an express server on the backend and react on the frontend. I intend to set up hot reloading in my app- whenever there's any change in the react code without having to refresh the whole app(HMR).</p>
  
  <p>I have <code>webpack-dev-server</code> and <code>HotModuleReplacementPlugin</code> installed. I've also tried to use <code>--hot</code> in the <code>webpack</code> script in <code>package.json</code>. If I run <code>npm run webpack</code>, the code compiles, and the server starts on <code>localhost:8080</code>. It gives me something like this, which is not what I want really. I don't know it looks like it's showing me the root directory.</p>
  
  <p><a href="https://i.stack.imgur.com/jITRb.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/jITRb.png" alt="enter image description here"></a></p>
  
  <p>On the other hand, if I run <code>npm start</code>, the server starts and displays the react component, which is what I want, but with hot reloading. Right now, I have to refresh the page in order to see the changes.</p>
  
  <p><a href="https://i.stack.imgur.com/ZSMuB.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ZSMuB.png" alt="enter image description here"></a></p>
  
  <p>So, I'm trying to understand what's really going on? Is there a way to add hot reloading when I type <code>npm start</code>?</p>
  
  <p><br><br></p>
  
  <p><strong>client/index.js</strong></p>
  
  <pre class="lang-js prettyprint-override"><code>import React from "react"
  import ReactDOM from "react-dom"
  import App from "./containers/App"
  
  ReactDOM.render(&lt;App /&gt;, document.getElementById("root"))
  </code></pre>
  
  <p><br></p>
  
  <p><strong>client/containers/App.js</strong></p>
  
  <pre class="lang-js prettyprint-override"><code>class App extends Component {
    render() {
      return (
        &lt;div&gt;
          &lt;Router&gt;
            &lt;Switch&gt;
              &lt;Route exact path="/" component={HomePage} /&gt;
            &lt;/Switch&gt;
          &lt;/Router&gt;
        &lt;/div&gt;
      )
    }
  }
  
  export default App
  </code></pre>
  
  <p><br></p>
  
  <p><strong>client/components/HomePage.js</strong></p>
  
  <pre class="lang-js prettyprint-override"><code>const HomePage = () =&gt; {
    return (
      &lt;div&gt;
        &lt;h1&gt;React HomePage&lt;/h1&gt;
      &lt;/div&gt;
    )
  }
  
  export default HomePage
  </code></pre>
  
  <p><br></p>
  
  <p><strong>routes/index.js</strong></p>
  
  <pre class="lang-js prettyprint-override"><code>var express = require('express');
  var router = express.Router();
  
  /* GET home page. */
  router.get('/*', function(req, res, next) {
    res.render('index', { title: 'Travel Forum' });
  });
  
  module.exports = router;
  </code></pre>
  
  <p><br>
  <strong>views/index.ejs</strong></p>
  
  <pre class="lang-js prettyprint-override"><code>&lt;!DOCTYPE html&gt;
  &lt;html&gt;
    &lt;head&gt;
      &lt;title&gt;&lt;%= title %&gt;&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
      &lt;div id="root"&gt;&lt;/div&gt;
      &lt;script src="/static/bundle.js"&gt;&lt;/script&gt;
    &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p><br></p>
  
  <p><strong>package.json</strong></p>
  
  <pre class="lang-js prettyprint-override"><code>  "scripts": {
      "start": "NODE_ENV=development nodemon ./bin/www",
      "webpack": "webpack-dev-server --config ./webpack.config.js --mode development --hot"
    },
  </code></pre>
  
  <p><br></p>
  
  <p><strong>webpack.config.js</strong></p>
  
  <pre class="lang-js prettyprint-override"><code>/* eslint-disable */
  var webpack = require("webpack")
  var path = require("path")
  const MiniCssExtractPlugin = require("mini-css-extract-plugin")
  
  module.exports = {
    mode: "development",
    devtool: "inline-source-map",
    entry: ["./client/index.js"],
    module: {
      rules: [
        {
          test: /\.(js|jsx)$/,
          exclude: /node_modules/,
          use: { loader: "babel-loader" },
        },
        {
          test: /\.(scss|css)$/,
          use: [
            { loader: MiniCssExtractPlugin.loader },
            {
              loader: "css-loader",
            },
            { loader: "sass-loader" },
          ],
        },
        {
          test: /\.(png|jpg|gif|jpeg)$/,
          use: [
            {
              loader: "file-loader",
              options: {},
            },
          ],
        },
      ],
    },
    resolve: {
      extensions: [".js", ".jsx"],
    },
    output: {
      filename: "bundle.js",
      path: __dirname + "/dist/bundle/",
      publicPath: "/static/",
    },
    plugins: [
      new webpack.HotModuleReplacementPlugin(),
      new webpack.DefinePlugin({
        "process.env": {
          NODE_ENV: JSON.stringify("development"),
        },
      }),
      new MiniCssExtractPlugin({
        filename: "bundle.css",
      }),
    ],
  }
  </code></pre>
  
  <p><br></p>
  
  <p><strong>app.js</strong></p>
  
  <pre class="lang-js prettyprint-override"><code>const createError = require("http-errors")
  const express = require("express")
  const bodyParser = require("body-parser")
  const path = require("path")
  const cookieParser = require("cookie-parser")
  const logger = require("morgan")
  const mongoose = require("mongoose")
  
  const indexRouter = require("./routes/index")
  const userRouter = require("./routes/users")
  
  const app = express()
  
  // view engine setup
  app.set("views", path.join(__dirname, "views"))
  app.set("view engine", "ejs")
  
  app.use(logger("dev"))
  app.use(express.json())
  app.use(bodyParser.json())
  app.use(express.urlencoded({ extended: false }))
  app.use(cookieParser())
  app.use(express.static(path.join(__dirname, "public")))
  
  if (process.env.NODE_ENV === "development") {
    const webpack = require("webpack")
    const webpackConfig = require("./webpack.config")
    const compiler = webpack(webpackConfig)
  
    app.use(
      require("webpack-dev-middleware")(compiler, {
        noInfo: true,
        publicPath: webpackConfig.output.publicPath,
      })
    )
  
    app.use(require("webpack-hot-middleware")(compiler))
  }
  
  mongoose.connect(
    "mongodb://localhost:27017/travel-forum",
    { useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false },
    function (err) {
      if (err) {
        console.log("Not connected to the database")
      } else {
        console.log("Connected to the database")
      }
    }
  )
  
  app.use("/api/v1/users", userRouter)
  app.use("/*", indexRouter)
  
  // catch 404 and forward to error handler
  app.use(function (req, res, next) {
    next(createError(404))
  })
  
  // error handler
  app.use(function (err, req, res, next) {
    // set locals, only providing error in development
    res.locals.message = err.message
    res.locals.error = req.app.get("env") === "development" ? err : {}
  
    // render the error page
    res.status(err.status || 500)
    res.render("error")
  })
  
  module.exports = app
  </code></pre>
  
  <p><br></p>