2015-09-30


In this tutorial we are going to build a character voting app (inspired by Facemash) for EVE Online - a massively multiplayer online game. You will learn how to build a REST API with Node.js, save and retrieve data from MongoDB, track online visitors in real-time using Socket.IO, build a single-page app experience using React + Flux with server-side rendering and then finally deploy it to the cloud.



Please consider disabling your ad blocker on this site.

100 min read

Overview
In this tutorial we are going to build a character voting app (inspired by Facemash and Hot or Not) for EVE Online - a massively multiplayer online game. Be sure to play this awesome soundtrack below to get yourself in the mood for this epicly long tutorial.

While listening to this soundtrack, imagine yourself mining asteroid belts in deep space while keeping a lookout for pirates on the radar, researching propulsion system blueprints at the station's facility, manufacturing spaceship components for capital ships, placing buy & sell orders on the entirely player-driven market where supply and demand govern the game economics, hauling trade goods from a remote solar system in a massive freighter, flying blazingly fast interceptors with a microwarpdrive or powerful battleships armored to the teeth, optimizing extraction efficiency of rare minerals from planets, or fighting large-scale battles with thousands of players from multiple alliances. That's EVE Online.
Each player in EVE Online has a 3D avatar representing their character. This app is designed for ranking those avatars. Anyway, your goal here is to learn about Node.js and React, not EVE Online. But I will say this: "Having an interesting tutorial project is just as important, if not more so, than the main subject of the tutorial". The only reason I built the original New Eden Faces app is to learn Backbone.js and the only reason I built the TV Show Tracker app is so that I could learn AngularJS. To me, either one of these projects is far more interesting than a simple todo app that everyone seems to be using these days.
One thing that I have learned — between screencasts, books and training videos, nothing is more effective than building a small project that you are passionate about to learn a new technology.


Source Code

In the same spirit as my previous tutorials (TV Show Tracker and Instagram Clone) this is a full-stack JavaScript tutorial where we build a complete app from the ground up.

Note
This is a remake of the original New Eden Faces (2013) project, which was my first ever single-page application written in Backbone.js. It has been running in production on OpenShift with Node.js 0.8.x for over 2 years now.
I usually try to make as few assumptions as possible about a particular topic, which is why my tutorials are so lengthy, but having said that, you need to have at least some prior experience with client-side JavaScript frameworks and Node.js to get the most out of this tutorial.
Before proceeding, you will need to download and install the following tools:

Node.js (or io.js)

Bower

MongoDB

gulp

nodemon

Step 1. New Express Project
Create a new directory newedenfaces. Inside, create 2 empty files package.json and server.js using your favorite text editor or using the command line:

July 22, 2015 Update: I am using the default Terminal app in Mac OS X with Monokai theme and oh-my-fish framework for the Fish shell.
Open package.json and paste the following:

These are all the packages that we will be using in this project. I will briefly go over each package.

Package Name

Description

alt

Flux library for React.

async

For managing asynchronous flow.

babel

ES6 compiler.

body-parser

For parsing POST request data.

colors

Pretty console output messages.

compression

Gzip compression.

express

Web framework for Node.js.

mongoose

MongoDB ODM with validation and schema support.

morgan

HTTP request logger.

react

React.

react-router

Routing library for React.

request

For making HTTP requests to EVE Online API.

serve-favicon

For serving favicon.png icon.

socket.io

To display how many users are online in real-time.

swig

To render the initial HTML template.

underscore

Helper JavaScript utilities.

xml2js

For parsing XML response from EVE Online API.

Run npm install in the Terminal to install the packages that we specified in the package.json.

Note
If you are using Windows check out cmder console emulator. It is the closest thing to Mac OS X/Linux Terminal experience.
Open server.js and paste the following code. It's a very minimal Express application, just enough to get us started.

Note
Although we will be building the React app in ES6, I have decided to use ES5 here because this back-end code is mostly unchanged from when I first built the original New Eden Faces project. Additionally, if you are using ES6 for the first time, then at least the Express app will still be familiar to you.
Next, create a new directory public. This is where we are going to place images, fonts , as well as compiled CSS and JavaScript files.

Run npm start in the Terminal to make sure our Express app is working without any issues.

Note
While you could technically use node server.js to start the app right now, as soon as we start writing the React app using ECMAScript 6 and pre-rendering it on the server, we will need the Babel compiler, in other words use babel-node server.js to start the app directly.
You should see the Express server listening on port 3000 message in the Terminal.

Step 2. Build System
If you have been around the web community at all, then you may have heard about Browserify and Webpack tools. If not, then consider the chaos that would arise from having to manually include so many <script> tags in HTML, in just the right order.

Furthermore, we cannot use ES6 syntax directly in the browsers yet. It first needs to be transformed into ES5 by Babel before serving it to users.
We will be using Gulp and Browserify in this tutorial instead of Webpack. I will not advocate for which tool is better or worse, but I will say that Gulp + Browserify is a lot more straightforward than an equivalent Webpack file. I have yet to find any React boilerplate project with an easy to understand webpack.config.js file.
Create a new file gulpfile.js and paste the following code:

Note
If you have not used Gulp before, this is a great starting point — An Introduction to Gulp.js.
Although the code should be more or less self-explanatory with those task names and code comments, let's briefly go over each task for completeness.

Gulp Task

Description

vendor

Concatenates all JS libraries into one file.

browserify-vendor

For performance reasons, NPM modules specified in the dependencies array are compiled and bundled separately. As a result, bundle.js recompiles a few hundred milliseconds faster.

browserify

Compiles and bundles just the app files, without any external modules like react and react-router.

browserify-watch

Essentially the same task as above but it will also listen for changes and re-compile bundle.js.

styles

Compiles LESS stylesheets and automatically adds browser prefixes if necessary.

watch

Re-compiles LESS stylesheets on file changes.

default

Runs all of the above tasks and starts watching for file changes.

build

Runs all of the above tasks then exits.

Next, we will shift focus to the project structure by creating files and folders that gulpfile.js is expecting.

Step 3. Project Structure
In the public directory create 4 new folders css, js, fonts and img. Also, download this favicon.png and place it here as well.

In the newedenfaces (project root), create a new folder app.
Then inside app create 4 new folders actions, components, stores, stylesheets and 3 empty files alt.js, routes.js and main.js.

In the stylesheets directory create a new file main.less which we will populate with styles shortly.
Back in the project root directory (newedenfaces), create a new file bower.json and paste the following:

Note
Bower is a package manager that lets you easily download JavaScript libraries, such as the ones specified above, via a command line instead of visiting each individual website, downloading, extracting and adding it to the project manually.
Run bower install and wait for the packages to be downloaded and installed into the bower_components directory. You can change that path using the .bowerrc file, but for the purposes of this tutorial we are sticking with the defaults.
Similarly to node_modules, you don't want to commit bower_components into a Git repository. But if you do not commit it, how will those files be loaded when you deploy your app? We will get back to this issue during the deployment step of the tutorial.
Copy all glyphicons fonts from bower_components/bootstrap/fonts into public/fonts directory.
Download and extract the following background images and place them into public/img directory:

Background Images.zip

Fun Fact
I have used the Gaussian blur in Adobe Photoshop in order to create that out of focus effect over 3 years ago when I built the original New Eden Faces project, but now it should be totally possible to achieve a similar effect using CSS filters.
Open main.less that we have just created and paste the CSS styles from the following file. Due to the sheer length of it, I have decided not to include it in this post.

main.less

If you have used the Bootstrap CSS framework in the past, then most of it should be already familiar to you.

Note
I have spent many hours designing this UI, tweaking fonts and colors, adding subtle transition effects, so if you get a chance, explore it in greater detail after you finish this tutorial.
I don't know if you are aware of the latest trend to include styles directly inside React components, but I am not sure if I like this new practice. Perhaps when tooling gets better I will revisit this topic, until then I will use external stylesheets like I always have been. However, if you are interested in using modular CSS, check out css-modulesify.
Before we jump into building the React app, I have decided to dedicate the next three sections to ES6, React, Flux basics, otherwise it may be too overwhelming trying to learn everything at once. Personally, I had a very hard time following some React + Flux code examples written in ES6 because I was learning a new syntax, a new framework and a completely unfamiliar app architecture all at once.
Since I cannot cover everything, we will only be going over those topics that you need to know for this tutorial.

Step 4. ES6 Crash Course
The best way to learn ES6 is by showing an equivalent ES5 code for every ES6 example. Again, I will only be covering what you need to know for this tutorial. There are plenty of blog posts that go in great detail about the new ES6 features.
Modules (Import)

Using the ES6 destructuring assignment we can import a subset of a module which can be quite useful for modules like react-router and underscore where it exports more than one function.
One thing to keep in mind is that ES6 imports are hoisted. All dependent modules will be loaded before any of the module code is executed. In other words, you can't conditionally load a module like with CommonJS. That did throw me off a little when I tried to import a module inside an if-else condition.
For a detailed overview of the import statement see this MDN page.
Modules (Export)

To learn more about ES6 modules, as well as different ways of importing and exporting functions from a module, check out ECMAScript 6 modules and Understanding ES6 Modules.
Classes
ES6 classes are nothing more than a syntactic sugar over the existing prototype-based inheritance in JavaScript. As long as you remember that fact, the class keyword will not seem like a foreign concept to you.

With ES6 classes you can also use extends to create a subclass from an existing class:

For more information about ES6 classes visit Classes in ECMAScript 6 blog post.
var vs let
The only difference between the two is that var is scoped to the nearest function block and let is scoped to the nearest enclosing block - which could be a function, a for-loop or an if-statement block.
Here is a good example showing the difference between var and let:

Basically, let is block scoped, var is function scoped.
Arrow Functions (Fat Arrow)
An arrow function expression has a shorter syntax compared to function expressions and lexically binds the this value.

Note
Parentheses around the single argument are optional, so it is up to you whether you want to enforce it or not. Some see it as a bad practice, others think it's fine.
Besides a shorter syntax, what else is it useful for?
Consider the following example, straight from this project before I converted it to ES6.

Every function expression above creates its own this scope. Without binding this we would not be able to call this.setState in the example above, because this would have been undefined.
Alternatively, we could have assigned this to a variable, e.g. var self = this and then used self.setState instead of this.setState inside the closures.
In any case, here is an equivalent ES6 code using fat arrow functions which preserve original this value:

Next, let's talk about React, what makes it so special and why should we use it.

Step 5. React Crash Course
React is a JavaScript library for building web user interfaces. You could say it competes against AngularJS, Ember.js, Backbone and Polymer despite being much smaller in scope. React is just the V in the MVC (Model-View-Controller) architecture.
So, what is so special about React?
React components are written in a very declarative style. Unlike the "old way" using jQuery and such, you don't interact with DOM directly. React manages all UI updates when the underlying data changes.
React is also very fast thanks to the Virtual DOM and diffing algorithm under the hood. When the data changes, React calculates the minimum number of DOM manipulations needed, then efficiently re-renders the component. For example, if there are 10,000 rendered items on a page and only

Show more