Love all that Facebook-made Javascript goodness but struggling to set up a well-oiled React environment? Fear not, through pain and shedding many a tear, I think I’ve finally figured out Webpack, Babel and other associated technologies. Let me show you how to set up a basic React environment with all its components, what they do and why they are included.

When I was getting started with Node development one of the biggest challenges was figuring out why all these bits and pieces were needed. For those of you who have some experience with Node and just want the nitty-gritty head on over to the repo on Github.

The Components

  • Babel compiles our fancy ES code into Javascript browsers and servers generally understand. This is similar to how Sass/Less needs to be compiled to CSS browsers can understand. ES uses syntax and conventions that are amazingly helpful, but a browser won’t be able to understand it without transformation thorough a compiler. Babel has a number of modules which allow you to support specific aspects of ES code which is why we’ll be installing a couple of babel related plugins.
  • Express is an extremely popular web application framework. It allows you to create a server and define routes.
  • React Router is a great Javascript Router. I use Express only to send every request to the main HTML file, everything else is handled by React Router.
  • React is our Javascript framework for creating front-end awesome. It is accompanied by react-dom which is the entry point for DOM-related rendering paths (no need to concern yourself with this one).
  • dotenv is for loading environmental variables from an .env file. This is useful for setting up environment specific differences. Eg: You may want to use a Stripe test API key locally but a live key in production.
  • Typestyle is something I’m still experimenting with but it looks like one of the best ways to manage styling of elements in a React environment.
  • Webpack is one of the most popular asset bundlers out there. It takes all your files with their dependencies and essentially shoves them into one big file. We’ll be installing some packages to make hot reloading happen: whenever you modify your code webpack rebuilds your static assets so you don’t need to run it manually each time.

Creating The React Environment

Installing Dependencies

First of all create a folder and run npm init within to generate a package.json file. Let’s install all our dependencies with two commands:

# Installing dependencies
npm i -S dotenv express react react-dom typestyle webpack react-router

# Installing dev dependencies
npm i -D babel-core babel-loader babel-preset-env babel-preset-react babel-preset-stage-0 webpack webpack-dev-middleware webpack-hot-middleware

Using Babel Presets

Since we’ve only installed the Babel presets we need to tell our application to use them. Create a .babelrc file and add the following within:

{
  "presets": [ "react", "env", "stage-0" ]
}

Public Directory

Create a directory which will act as our public root folder. It will contain a single HTML file linking to a bundled JS file which will be created ad-hoc by Webpack. Create a public directory and create index.html within it using the following code:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="shortcut icon" href="favicon.ico">
    <title>My React Environment</title>
  </head>
  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="app" style="height:100%"></div>

    <script type="text/javascript" src="/bundle.js"></script>
  </body>
</html>

In a local environment that /bundle.js won’t exist – Webpack will compile it on-the-fly. In a production environment you would run Webpack to actually create the file and then start your server.

Environment Variables

Create a .env file which you’ll use to store a number of environment specific variables. For now let’s just add a port number, say 7754.

PORT=7754

Webpack Config

require('dotenv').config();
var webpack = require('webpack');

module.exports = {
  devtool: 'eval',
  context: __dirname + "/src",
  entry: './index.js',
  output: {
    filename: 'bundle.js',
    path: __dirname + "/public",
    publicPath: '/'
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader",
      },
    ]
  },

  plugins: [
    new webpack.optimize.ModuleConcatenationPlugin(),
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.NamedModulesPlugin(),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': JSON.stringify('development')
      }
    }),
    new webpack.EnvironmentPlugin([
      'PORT',
    ])
  ]
}

This seems convoluted but it’s not that bad. Take a look at the Webpack docs for detailed explanations.

The Server

Our server configuration may seem a little complex if you’re new to all this. Add the code below to server.js within a bin folder.

// Including thigies we need
require('dotenv').config();
var express = require('express');
var path = require('path');
var server = express();

// All this is just for hot reloading
var webpack = require('webpack');
var webpackConfig = require('../webpack.config');
var compiler = webpack(webpackConfig);
var publicDir = path.resolve(__dirname, '../public')
server.use(require("webpack-dev-middleware")(compiler, {
    noInfo: true, publicPath: webpackConfig.output.publicPath
}));
server.use(require("webpack-hot-middleware")(compiler));


// Serving static files from our public dir
server.use(express.static(publicDir + '/'));

// Rout everything to index.html
server.get('*', function(req, res){
  res.sendFile(publicDir + '/index.html');
});

// Listen on the given port
server.listen(process.env.PORT, () =&gt; {
  console.log('Listening on port ' + process.env.PORT);
});

Finally, we need to be able to run this script. In your package.json file add the following:

"scripts": {
  "start": "node bin/server.js"
},

The React Application

We can finally start to create our React app! Make a folder named src and plop and index.js into it with the following code:

import React from 'react';
import {render} from 'react-dom';

class App extends React.Component {
  render () {

    return <p> Hello React!</p>;
  }
}

render(<App/>, document.getElementById('app'));

All Done

The concludes the setup of a simple React environment. If you’d like to see the code take a look at the Github repository. Since it will certainly evolve over time, here’s a Zip file containing the initial version explored in this article.