NPM, Webpack, Babel, and ReactJS — Configuring Your Tools

Steven Leiva
6 min readMar 17, 2016

--

Spurred by the positive experience I have had over the past two months developing in ReactJS, I have decided to try my hand at building a web application with Node.js and Express. I decided on Express because I wanted to avoid the complexity and overhead that comes with the “batteries included” approach of frameworks such as MEAN, SailJS, or Meteor. Eventually, the goal is to “graduate” to those frameworks, but they are not the right vehicle for a beginner to learn back-end JavaScript.

As it turns out, despite my attempts to wade into the shallow end of the pool, there is a lot of configuration that I ended up performing before even contemplating my first line of var express = require(‘express’);. In this post, I’d like to briefly outline the tools, how to configure them, and how I figured it all out. (This last part is particularly important, since this article will be outdated sooner rather than later). Finally, be warned that, because I’d like to mimic the steps I actually took, we might be jumping back and forth a bit between tools.

Note: Before proceeding with the rest of this article, make an empty directory with the desired name of your project:

mkdir helloWorld

NPM

npm is the node package manager. It is installed alongside node, and its job is simply to allow you to install applications from npmjs.com, track which versions of those applications you are using, and allow for easy updating / locking of versions.

The good news is that there is no configuration that you need to make for the package manager itself. Instead, you just run npm init in your app’s root directory, and answer a few questions!

This will produce a package.json file that we will modify, slightly, later on.

Webpack

Webpack is a “bundler for modules”. All this means is that it takes a bunch of files that you have written, and creates a single file out of it. This is necessary because developers want to be able to separate their code into different files / modules to aid organization and maintainability, but a node program is nothing more than a single JavaScript file. Webpack solves this problem — a bunch of files in, one or two files out!

Installing webpack is easy — we can run:

npm install --save-dev webpack

This will install webpack as a developer dependency, meaning that if others are using our project, but not developing on it, they can easily skip installing webpack.

After installation, we need to configure webpack. We do this by creating a webpack.config.js file in our app’s root directory, and then taking 5 minutes to read these docs, more specifically, the A Config File section.

Webpack has a traditionally high learning curve. However, for our needs (for now), are simple. Our webpack.config.js file will look like this:

module.exports = {
entry: “./app.js”,
output: {
path: __dirname + “/dist”,
filename: “bundle.js”
}
};

Let’s take a look at what we’ve done. First, we’ve added an entry property to the object we are exporting. This tells webpack where our main file is. This main file itself is not required anywhere else. It requires other files, which require other files, which make up the entire application.

Secondly, we have provided an output property. This property points to an object that has an path property, which tells webpack what directory to place the new, combined file. Finally, filename tells webpack what to name the file. That’s it! Now, wepback knows how to take app.js, any files it requires, and any files they require, into one file called bundle.js.

Babel

Now that we’ve set up webpack, let’s integrate it with babel. To do that, we simply follow the directions on Babel’s website. The website is very self-explanatory. We simply chose the tool we’d like to integrate babel with, and directions for how to do so will automagically show up.

First, we want to make sure that we install babel as a dev dependency:

npm install --save-dev babel-loader babel-core

Now, that it’s installed locally to our project, we can edit the webpack.config.js file. We’re going to be adding a module property that points to an object with other nested attributes:

module: {
loaders: [
{ test: /\.js$/, exclude: /node_modules/, loader: "babel-loader"}
]
}

This piece of code is directing webpack to process any file ending in .js* through babel-loader. (/\.js$/ is a regular expression that the files will be matched against.). We are also directing webpack to ignore files stored in teh node_modules directory when doing this processing.

At this point, our webpack.config.js file will look like this:

At this point, however, while webpack is doing its job just fine, babel is not doing a single thing. This is because, as the documentation reads, “Babel 6.x does not ship with any transformations enabled”. At a minimum, I am guessing that you want to write your new awesome web app using ES6 syntax — let’s enable that!

Bable — ES6 Syntax

First, we need to install a preset that Babel can work with. To enable ES6 transformations — i.e., to be able to write ES6 and have Babel + Webpack transpile that into valid ES5 — we can install babel-preset-es2015

npm install — save-dev babel-preset-es2015

Now that we have that available, we can create a .babelrc that instructs Babel which transformations we want to make:

{ presets: [ “es2015”] }

Now, Babel knows that we want to transpile our code using the es2015 preset.

ReactJS

Finally, we want to install and use ReactJS. Again, first, let’s install ReactJS:

npm install --save react react-dom

Now that ReactJS has been installed, we want to instruct Babel to transform our files using the babel-react preset. To do this, install the preset.

npm install --save-dev install babel-preset-react

Now, we can configure babel to use this preset. In our .babelrc file, we simply add “react”, such that our entire .babelrc file looks like the below:

{ presets: [ “es2015”, “react” ] }

We Have a Minimal Starter Pack

Let’s recap what we have done.

First, we installed a few dependencies for our project, including babel-core, babel-loader, babel-preset-es2015, babel-preset-react, and webpack. All of these should be dev dependencies. They are only used to compile, in a sense, our application.

Secondly, we have configured webpack through our webpack.config.js file. In it’s entirety, the file should look like this:

Thirdly, we have configured babel through .babelrc file. The final version of that file should look like this:

{ presets: [ “es2015”, “react” ] }

That’s it! Now, we can write ES6 and ReactJS code inside of app.js, and then we can run webpack in a terminal, and it will take care of creating a single bundle.js file inside of <app root>/dist/.

A Little Less Manual

In the last bit of configuration, we are going to modify the package.json file that was the result of running the npm init command earlier in this tutorial.

We’re going to add a top-level property called scripts, which will point to another object consisting of a few strings:

“scripts”: {
“start”: “webpack —- progress —- colors —- watch -d”,
“build”: “webpack —- progress —- colors --p”,
“test”: “echo \”Error: no test specified\” && exit 1"
}

What we are doing here is providing commands that npm can run for us. For example, if I type npm run start at the command line, npm will run that string as if I had typed it into the command line.

So, our entire package.json will look something like this:

Here, we’ve passed a few flags to webpack. Let’s decipher what they do. We can find an explanation of these features at the official documentation website, we can get access to webpack’s documentation and figure this out.

— progress: displays a progress bar

— colors: enables color-coded output

— watch: this flag is very useful. It watches all of our development files, and will recompile on the fly if there are changes in any of them.

The End!

--

--