Setting Up DevServer With Hot Reloading Using WebPack 4 and React

Craig Stroman
5 min readAug 14, 2020

When developing a React app you have some options for how to set up your environment. One of the easiest ways to create a React app is to use Create React App. But you might want to have your own custom setup using React and WebPack with DevServer. In this post I’ll show you how to set that up.

Now once you have a directory created for your project navigate to it using the terminal. Once you are in the project directory start a Node project if you haven’t already. You can do that by running the following command:

npm init -y

The -y option will just automatically accept the default options that NPM will ask you about. The next commands will just be installing all the packages that you need. Since I’ll be using React with the project I’m going to install React running the following command:

npm --save install react react-dom

That will install the React, and ReactDom modules you can use. The next command I run will install the latest version of WebPack which is version 4, WebPack CLI, Web Pack Dev Server, and html-webpck-plugin which is also needed. I will also be using Babel, Sass Loader, and Style Loader, CSS Loader, with this example. That’s usually my React setup.

npm --save-dev install webpack webpack-cli webpack-dev-server html-webpack-plugin @babel/cli @babel/core @babel/polyfill @babel/preset-env @babel/preset-react babel-loader sass-loader style-loader css-loader uglifyjs-webpack-plugin

Now it’s time to set up the WebPack config files. I like having a prod config file and a dev config file. The command you can run to create these files is the following:

touch webpack.config.dev.js; touch webpack.config.prod.js;

Putting the ; in between the commands means you can run them both at the same time if you didn’t already know that. Next we will be editing the config files so you’ll need to open them in the editor you use. I have always liked SublimeText but lately I’ve started using Microsoft Visual Studio.

The file I’m going to show you how to set up here is the dev config file. You can view how to setup the prod config file in the GitHub repo that I setup for this post.

With webpack.config.dev.js open the next thing you have to do is import all the needed modules. You can do that by including the following lines of code:

const path = require('path');
const webpack = require('webpack');
const HtmlWebPackPlugin = require('html-webpack-plugin');

In my configurations I tend to use variables to hold filenames, and paths. I might usually do that by declaring the following:

const filePath = path.join(__dirname, './public/js/');
const fileName = 'bundle.js';
const PATHS = {
src: path.join(__dirname, './src/'),
dist: path.join(__dirname, 'public'),
};

Next we have to define the main configuration module and exporting it. We do that by writing the following:

module.exports = {}

Now we have to define some of the main settings for WebPack. We can do that by adding the following:

mode: 'development',devtool: 'source-map',entry: {
app: [path.join(__dirname, './src/App.jsx')],
},
output: {
path: PATHS.dist,
filename: fileName,
publicPath: '/',
},
watch: true,
watchOptions: {
ignored: '/node_modules/',
},
resolve: {
extensions: ['.js', '.jsx'],
},

Mode is set to development, devtool will make WebPack produce source maps, entry is the starting point of your app. Which I usually put my source code within a src directory and usually my main app file is App.jsx.

Output is where you want the bundled file to be placed. Usually that would be within the /public/ directory that’s located in the root of your project. Watch tells WebPack to watch files for changes, while watchOptions is where you place a set of options that are used to customize watch mode like files and directories to ignore.

The next set of options where going to configure is for how WebPack will treat different types of modules being used within the project. We can define that by adding the following below resolve from above:

module: {
rules: [
]
}

Within module is where we will define how WebPack uses Babel and the SASS files within the project. We can set up Babel by adding the following to the rules array:

{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
sourceMaps: true,
presets: ['@babel/preset-env', '@babel/preset-react'],
plugins: [],
},
},
},

The next thing we need to define is how WebPack will handle our SASS files. That can be done by adding the following after are Babel settings within the rules array:

{
test: /\.scss$/,
use: [
{
loader: 'style-loader', // creates style nodes from JS strings
},
{
loader: 'css-loader', // translates CSS into CommonJS
},
{
loader: 'sass-loader', // compiles Sass to CSS
},
],
},

Now after the module settings were going to configure how the dev server works and how hot reloading works. To do that add the following:

devServer: {
contentBase: PATHS.dist,
compress: false, historyApiFallback: true, hot: true, port: 3000,
},

Once we have that set up we then have to configure plugins where using. For this example I’m just using the HTML WebPack plugin. You can add this after the devServer settings by adding the following:

plugins: [
new HtmlWebPackPlugin({
template: path.resolve(__dirname, 'public/index.html'),
filename: 'index.html',
}),
],

Now we have to create the .babelrc file within the root of our project by running the following command:

touch .babelrc;

We now have to update our babel settings within the .bablerc file. The following is what needs to be placed there:

{
'presets': ['@babel/preset-env', '@babel/preset-react']
}

Once that’s done you have to create a HTML file within the public folder. I just create a file called index.html like so:

<!DOCTYPE html>
<html class="no-js">
<head>
<meta charset="utf-8" />
<title>Test App</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<div id="app"></div>
</body>
</html>

After that you need to create a React app, and for this I will just create a simple one file app within the src directory called App.jsx with the following contents:

import ReactDOM from 'react-dom';
import React from 'react';
const App = (
<div>
Hello World
</div>
);
ReactDOM.render(App, document.getElementById('app'));

Once that’s done we then have to edit our package.json file and add the script we use to start our server. How I do that is normally the following:

"start": "NODE_ENV=development webpack-dev-server -d --config ./webpack.config.dev.js"

After you’ve done that you should be able to start your server by running npm start in the terminal. The web page will be available at http://localhost:3000. If you make a change to /src/App.jsx your page will now automatically refresh and show you the changes.

The repo I created for this post is available here.

--

--