The MERN Challenge: Building the FCC Twitch App using MongoDB, Express, Reactjs, and Nodejs

Adham El Banhawy
5 min readFeb 22, 2018

So I’m a quick learner. Just a little over a year ago all I know about web development was HTML, CSS, and Javascript. I learned my basic front-end skills from following the front-end challenges and projects on freeCodeCamp. And still with these basic skills I managed to get an internship/part-time job as web developer in the university I attended.

But that was just me getting my foot in the door.

I found myself fascinated by the advanced topics and frameworks that surrounded web development. I saw and worked with powerful devs who just seemed like wizards to me. But that only inspired me to learn more and DO more. Long story short, I decided to become a fullstack developer and I am trying to master the MERN stack at the moment. Hence why I am building the twitch project using MongoDB, Express, React, and Node.

In this post I will only go through my server setup and configuration.

Using C9 Editor

If you haven’t heard about C9 I recommend that you try it out at least once. It’s a great online platform to collaborate, edit, and test your code. It’s basically a remote linux server that you can access in the browser, and it’s available 24/7 for free.

Nodejs, NPM, and ES6

This app is going to be built on a node server that is going to supply api data, connect to a database and host the React app. However, first I’m going to make sure I’m using the latest stable release of Node.js to so I can make use of ES6 syntax. To do that I will install and use the latest stable release of Node (which is 8.9.4 at the time of writing this post):

nvm install 8.9.4

After install check node version “node -v” . If the environment hasn’t switched to the newer version, then use it using the command:

nvm use 8.9.4

And let’s do initialize git to track our code history and npm to manage our node modules:

git init
npm init

The following is the list of the node modules I install and use as listed in my package.js file:

{
"name": "twitch-streamers",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"sass": "node-sass -w --output-style compressed src/assets/styles -o public/",
"start": "nodemon --exec babel-node server.js --ignore public/ && npm run sass",
"dev": "webpack -wd"
},
"author": "",
"license": "ISC",
"dependencies": {
"axios": "^0.18.0",
"ejs": "^2.5.7",
"express": "^4.16.2",
"mongodb": "^3.0.2",
"node-sass": "^4.7.2",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-router-dom": "^4.2.2"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-eslint": "^8.2.1",
"babel-loader": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-2": "^6.24.1",
"eslint": "^4.18.0",
"eslint-plugin-react": "^7.6.1",
"json-loader": "^0.5.7",
"jsx-loader": "^0.13.2",
"file-loader": "^1.1.9",
"img-loader": "^2.0.1",
"nodemon": "^1.15.0",
"url-loader": "^0.6.2",
"webpack": "^3.11.0"
}
}

I use nodeman execution wrapper to automatically restart my node server whenever I change and save the server files. Notice that I use babel-node to run the server.js. This is the babel-cli in action and it has the same functionality as node command except it compiles ES6 syntax, so I can use import statements and other ES6 features in my server.js.

My sass script just watches my sass files for changes and compiles to compressed css. The dev script runs webpack.

Webpack and Babel configuration:

I decided not to go with create-react-app because I know from a previous hackathon experience how tedious it is to use it with an express server and to customize the webpack configurations. So I seized the opportunity to learn more about webpack and babel and to be more in control.

Here’s my webpack.config.js:

const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, './public'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /.js$/,
use: [
'babel-loader'
]
},
{
test: /.json$/,
use: [
'json-loader'
]
},
{
test: /.jsx$/,
use: [
'babel-loader'
]
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
'url-loader?limit=10000',
'img-loader'
]
}
]
}
}

And here’s my .babelrc file:

{
"presets": ["react", "es2015", "stage-2"]
}

Start an Express Server

I like to keep my environment variables in a separate file. Here’s my config.js:

const env = process.envexport default {
port: env.PORT || 8080,
host: env.HOST || '0.0.0.0',
get serverUrl() {
return `http://${this.host}:${this.port}`
}
}

This file exports an object containing the environment port and host, as well as the serverUrl() function that returns the server’s url. This will come in handy in the express server.

In server.js, import (remember I can use import here instead of require because I am using babel) the configuration file and express:

import express from 'express'
import config from './config'
//Instantiate the server
const server = express()
// Test response
server.get('/', (req, res) => {
res.send('Why Hello There')
})
//Serve files from the public directory
server.use(express.static('public'))
//Listen given port
server.listen(config.port, config.host, ()=>{
console.info('Express listening on port ', config.port)
})

In the code above, I instantiate an express server and instruct it to serve files from the folder I called “public”. This folder will hold the compiled html, js, and css.

The server is now programmed to receive requests to the root domain, i.e. the ‘/’, and to respond with the string “Why Hello There”.

Finally I set the server to listen to the port and host I specified in the config file earlier.

Now all you have to do to start the server is the following:

npm start

The result should look a little something like this:

So that’s how you write server, huh? Not so scary now!

And now we have the backend of the application pretty much setup!

In the next article I will move on to use React on to of Express and set-up the front-end that we deserve.

Stay tuned!

--

--

Adham El Banhawy

Software Developer, blogger, and tech enthusiast. Previously @ IBM. Currently Cloud consulting.