All Articles

Setting up a React Development Environment from Scratch.

Introduction

Working with React is great. But unfortunately creating a react development environment is quite painful for a beginner and the ever changing Javascript community makes it even more complicated and cumbersome. You need to be familiar with technologies such as Babel, Webpack, ESLint and a couple of other things that might not be immediately apparent to a beginner. Along the way we’re going to talk about the various technologies we need, why we need them and how they make our lives easier. Obviously, you can just use CRA but I believe every react developer should know how to create an environment specific to their needs and particular development preferences.

This article is mostly targeted at beginner web developers who have experience building web applications and are looking to learn react. To follow along you should be familiar with Javascript and ES6 syntax. Let’s get started :fire:

First Steps..

To begin we need to have node and npm installed correctly. If you don’t have it you can use this link to install the latest long term support version. Follow the installation instructions to get it setup. Open up a terminal (command prompt for windows) and type in the command node -v, you should get the node version number if you installed it correctly.

Now,can create a new project called React-boilerplate using the following commands in your terminal mkdir React-boilerplate && cd React-boilerplate. Then run npm init. This will initialise a new node project and create a package.json file with some basic information.

Babel

Babel is simply a javascript compiler that is used to convert es6^ code into backward compatible syntax that can run in older environments and browsers (SRC here?).

To install babel run the following command in your terminal;

npm i @babel/core @babel/node @babel/preset-env @babel/preset-es2015 @babel/preset-react -D

We also need to install a couple of babel plugins that make our development life much easier.

npm i @babel/plugin-syntax-dynamic-import @babel/plugin-proposal-class-properties @babel/plugin-proposal-export-namespace-from @babel/plugin-proposal-throw-expressions -D

Next we need to create a .babelrc file that serves as the configuration file for babel.

{
    "presets": [
      "@babel/env",
      "@babel/react",
    ],
    "plugins": [
      "@babel/plugin-syntax-dynamic-import",
      "@babel/plugin-proposal-class-properties",
      "@babel/plugin-proposal-export-namespace-from",
      "@babel/plugin-proposal-throw-expressions"
    ]
}

To make sure everything works correctly. Lets setup a basic express server with some ES6 syntax. Install express using npm i express -S and create a new server.js file with the following code.

import express from 'express';

const app = express();

const port = 3000;

app.listen(port, () => { console.log(`App is listening on port ${port}`) });

app.get('/', (req, res) => {
    res.send(' Hello World :) ');
 });

And modify your scripts in your package.json like so;

"scripts": {
    "start:dev": "babel-node server.js"
  },

Visit http://localhost:3000/ and you should see the Hello World message.

Webpack and React

Now that we have babel setup correctly we can now setup webpack and react. Very quickly Webpack is a module bundler for javascript applications (You can read this great article for more information). Basically, webpack consists of a configuration file that is simply a javascript object that consists of configurable options. Firstly we need to install webpack and a couple of more packages.

npm i webpack webpack-cli webpack-dev-middleware webpack-dev-server webpack-hot-middleware node-sass style-loader css-loader babel-loader mini-css-extract-plugin html-webpack-plugin -S

To move forward lets create a new file webpack.config.js in our root directory. Check the annotations for context.

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

// HtmlWebpackPlugin is used to inject our created bundles into this html file so // we need to create it.
const HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
    template: './src/index.html',
    filename: 'index.html',
    inject: 'body',
});

module.exports = {
    target: 'web',
    devServer: {
        port: 3000,
        contentBase: './dist',
    },
    entry: {
        app: ['./src/App.jsx'],
        vendor: ['react', 'react-dom']
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'js/[name].bundle.js'
    },
    devtool: 'source-map',
    resolve: {
        extensions: ['.js', '.jsx']
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /(node_modules)/,
                use: ['babel-loader'], // we use this to transpile es6 code on the web
              },
              {
                test: /\.css$/,
                use: [
                  MiniCssExtractPlugin.loader,
                  "css-loader", "postcss-loader",
                  ],
                },
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "styles.css",
            chunkFilename: "styles.css"
        }),
        HtmlWebpackPluginConfig,
        new webpack.NoEmitOnErrorsPlugin(),
    ],
    mode: 'development',
}

Create a new directory called src (this is where we’ll house our react application :) ). Within that directory create a new index.html file like so.

./src/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>React Boilerplate</title>
</head>
<body>
    <div id="root"></div>
</body>
</html>

Now we can install react and react-dom. npm i react react-dom -S. After we create a new App.jsx file within the root directory.

import React from 'react';
import ReactDOM from 'react-dom';


const rootEl = document.getElementById('root');


const App = () => {
    return (
        <div>
            <h1 style={{ 'textAlign': 'center'}}> Hello World :) </h1>
        </div>
        );
};

const renderApp = () => {
    ReactDOM.render(
        <App />, rootEl
    );
}

renderApp();


// This checks for local changes and automatically refreshes the browser (hot-reloading)
if (module.hot) {
    module.hot.accept('./components/App.jsx', () => renderApp());
}

Before we can view our React application we need to modify our start:dev script (as its still pointing to our express server) to use our newly created webpack config

"scripts": {
    "start:dev": "webpack-dev-server  --config webpack.config.js"
  },

Visiting http://localhost:3000/ and you should see the following Screen Shot 2019-01-30 at 9.39.06 PM.png

Next Steps..

And thats it! Well done if you followed all the steps.You should know have a nice boilerplate you can use when building your own react applications. There’s still more work to be done. We didn’t setup a linter(EsLint) or configure our application to run in production mode. Also our express server is pretty useless now, we should replace webpack-dev-server and use express to serve our application instead :thinking: :thinking:. We’ll get to that in part 2! All the code is live here on github.