Building a Dev Server with Express and Webpack

(This post picks up where my previous post, about building a React app from scratch, left off. I recommend reading it first if you haven’t used Webpack before.)

I recently built my first React app without using the create-react-app command, and — riding a wave of JavaScript confidence from the accomplishment — I decided to dig deeper and try to build my own development server using Node.js.

My goal was to build a server that would (1) serve theindex.html page of my single-page React application and (2) hot reload (i.e., re-compile my code and refresh the browser) each time I made changes to my code.

Express.js

I was able to accomplish goal #1 quickly using Express. All I had to do was install the framework:

npm i --save-dev express

Then, create a single server.js file in my project’s root directory with the following:

And lastly, run the server with Node:

node server.js

This server technically works, but it’s very tedious to use. I have to manually re-compile my project each time I start the server and anytime I make changes to my code. That is not ideal.

What I need is a way to tell Webpack to compile my project in my Node environment.

Running Webpack in Node

Bringing Webpack into my Node environment was more intuitive than I thought it would be. Webpack exports a function that takes a Webpack configuration object as its argument. This function compiles our code:

The webpack() function returns a compiler object that can be used to serve the final product. First, I’ll need to add some middleware to help:

npm i --save-dev webpack-dev-middleware

Then, import the middleware and replace the express.static call I was using before:

So now when I run node server.js, Webpack compiles my code first and then serves the generated index.html with my bundled JavaScript. I’ve checked-off goal #1. Let’s see about goal #2, adding hot reload.

Adding hot reload

To add the hot reload feature to our server, all we need to do is add another bit of middleware to our dependencies:

npm i --save-dev webpack-hot-middleware

And tell our server to use it:

Now, Webpack re-compiles my code anytime I make a change and refreshes my browser, rendering the changes.

In the end, I have an extremely bare server that hot-reloads each time I make changes. It’s usable for any development build, but there is one small problem I wasn’t able to overcome.

If you follow along and build a server identical to mine, you’ll notice that it starts listening for requests before Webpack finishes compiling the project. I tried a number of different strategies for fixing this, but couldn’t get any of them to work properly.

I ended up just using setTimeout() as a hack to delay my server while Webpack does its thing. If anyone reading this figures out how to fix this, respond to this story and let me know.