Make a React dev-environment with your own hands
Tags: react, javascript, node
Published: 2018-09-27 01:43:53

---
title: Make a React dev-environment with your own hands
published: true
description: Learn how create your own development environment for ReactJS
tags: react, javascript, node
cover_image: https://fitzdecarts.com/wp-content/uploads/2018/03/All-Hands-Background-Wallpaper.jpg
---

Hello React hackers. In this post I'm going to explain how create a dev evironment for ReactJS. The creation of this environment can be done automatically just installing this package: `create-react-app` But if you are like me, a lover of the absolute control in your apps and you want get your hands dirty learning from the core, well. Let's get start.

> NOTE: This post assumes that you have npm and nodejs in your terminal

To our dev-env we're going to need some dependencies:

* react
* react-dom
* webpack
* babel

Also we're going to need some friends (plugins and presets) that I'm going to explain a few lines bellow.

## Part 1 - Dependencies

### 0 - Starting

Make a root folder, you can name it whatever you want. The name is your decision, i'm going to name it `reactenv`. Inside the folder, generate the `package.json` file

    C:\users\anderson\desktop\reactenv > npm init

you can answer the questions about the module as you like.

### 1 - React

Let's continue with one of the our principal dependecy. React and React-Dom.
The react package contains the necessary functions to define, create and utilize react components, so we can render them later in our DOM.
On the other hand, the react-dom package will be our comunicator between React and the DOM, well it has as objective render react components.

Let's install these two:

    C:\users\anderson\desktop\reactenv > npm install react react-dom --save
    
### 2 - Webpack

[Webpack](https://webpack.js.org/) is a tool that can pack resources for web apps. Can manage HTML, CSS, JS, and even those who need to be transformed like SASS or JSX.
In this case we're going to use it for pack react files and modules.
So, we'll need webpack, and webpack-cli, this last one we're going to use it for send options and arguments to webpack at the moment to make the package.

    C:\users\anderson\desktop\reactenv > npm install webpack webpack-cli --save
    
### 3 - Babel

[Babel](https://babeljs.io/) is Just a javascript compiler, that allows us transform our modern javascript code in compatible-browser javascript code.

We're going to need the following dependencies related to babel:
`babel-core`: is just the compiler core
`babel-loader`: Allow transpile javascript code using webpack
`babel-preset-env`: Is a preset that translate ES2015+ in ES5
`babel-preset-react`: Includes the functionalities to work with react, one of the most importants is transform the JSX code in JS understable for the browsers

    C:\users\anderson\desktop\reactenv > npm install babel babel-core babel-loader babel-preset-env babel-preset-react --save

And Done! We have ready our dependencies. Let's continue with the configuration.

## Part 2 - Configuration

To start the configuration we need create a file structure inside of our folder. The file structure is the following: 

![](https://i.imgur.com/h8Wm6cC.jpg)

Let's start configuring our webpack. Inside `webpack.config.js` let's add the next code:

`.\reactenv\webpack.config.js`

```js
const path = require('path');

module.exports = {
  entry: './public/js/app.js', // Entry point to pack
  output: {
    path: path.resolve('public/js'),
    filename: 'bundle.js' // Output usable to add in our index.html
  },
  mode: 'development',
  module: {
   rules: [
     {
       test: /\.js$/, // Send any .js file (excluding node_modules) to babel compiler
       exclude: /node_modules/,
       use: {
         loader: "babel-loader"
       }
     }
   ]
 } 
};
```

Knowing that our code will be in `.\js\bundle.js` we can add it to our `index.html` Which will contain a simple markup to demonstrate that our environmet is working.

This is how our index.html should looks 
`.\reactenv\public\index.html`

```html
<!DOCTYPE html>
<html>
   <head>
      <title>Hey React</title>
   </head>
   <body>
      <div id = "content"></div>
      <script src = 'js/bundle.js'></script>
   </body>
</html>
```

Simple. Now let's go to the configuration of babel in our file `.babelrc`
`.\reactenv\.babelrc`

```
{
   "presets":["env", "react"]
}
```
We're just defining which presets will use babel at the moment of compile our code

Now, finally. Let's start with our javascript/react file

`.\reactenv\public\js\app.js`

```javascript
import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class Hello extends Component {
  render() {
    return(
      <div>
        <h1>Hello react</h1>
      </div>
    );
  }
} 

ReactDOM.render(
  <Hello />,
    document.getElementById('content')
);
```

With all we've done, our react app should work. Let's see.
Before to compile our React/JSX code, let's add the next script to our `package.json`

```javascript

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
 ++ "build": "webpack --mode production"
  }

```
Let's run

```
C:\users\anderson\desktop\reactenv > npm run build
> webpack --mode production

Hash: 36a78e225a265111c0fb
Version: webpack 4.19.1
Time: 16609ms
Built at: 2018-09-26 17:53:25
    Asset     Size  Chunks             Chunk Names
bundle.js  103 KiB       0  [emitted]  main
Entrypoint main = bundle.js
[3] ./public/js/app.js 2.71 KiB {0} [built]
    + 7 hidden modules
```

and voilá

![](https://i.imgur.com/PFkmJJg.png)

We dont want run `npm run build` every time that we make a change in our app, so let's create a server to automatize this process.

let's add this code to `server.js`

`.\reactenv\server.js`
    
```javascript
const child_process = require('child_process');
const http = require('http');
const fs = require('fs');

const base = 'public/';

const server = http.createServer();

// Request event
server.on('request', function(request, response) {
  const path = base + request.url;
  // check the status of file requested
  fs.stat(path, (err, stats) => {
      if(err) { // if not exist 404
        console.log('ERROR 404 on file: ' + path);
        response.end('error 404');
      } else { // if exist read it and show it
        fs.readFile(path, (err, data) => {
          console.log('200 OK! file: ' + path);
          response.write(data);
          response.end();
        });
      }
  });
});

// localhost port
server.listen(3000);
console.log('server running on 3000');

// variable to prevent multiple calls
let webpackRunning = false;
function runWebpack() {

  // if webpack is already running don't call it again
  if(webpackRunning) {
    return;
  }
  console.log('app.js changed | running webpack...');

  webpackRunning = true;
  // create a new node process with webpack path and arguments
  const nodeProcess = child_process.fork('node_modules\\webpack\\bin\\webpack.js', ['--mode', 'production'] );

  nodeProcess.on('error', (error) => {
    throw error;
  });

  nodeProcess.on('exit', (code) => {
    console.log('Exit-code: ' + code);
    webpackRunning = false;
  });
}

// if our app.js file change then run web pack
fs.watch('public\\js\\app.js', (eventType, filename) => {
  if(eventType === 'change') {
    runWebpack();
  }
});

```

Once the server code is ready, let's add it to npm scripts

```javascript
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --mode production",
 ++ "start": "node server.js"
  }
```

Let's try. If everything went well, we'll see something like this:

```
C:\users\anderson\desktop\reactenv > npm start

> node server.js

server running on 3000
```
If we go to localhost:3000 in our browser we will see our 'Hello react' message. Let's make a change in `app.js` to check automatic compilation:

`.\reactenv\public\js\app.js`

```javascript
class Hello extends Component {
  render() {
    return(
      <div>
        <h1>Hello react</h1>
     ++ <p>Let's Code</p>
      </div>
    );
  }
} 
```

When we save the file, we'll see this in our terminal:

```
app.js changed | running webpack...
Hash: ada89837b72385fcf901
Version: webpack 4.19.1
Time: 10672ms
Built at: 2018-09-26 18:15:06
    Asset     Size  Chunks             Chunk Names
bundle.js  103 KiB       0  [emitted]  main
Entrypoint main = bundle.js
[3] ./public/js/app.js 2.75 KiB {0} [built]
    + 7 hidden modules
Exit-code: 0
```

that means that our file was compiled successfully. Let's check our localhost.
![](https://i.imgur.com/qDaK1fv.png)

It works! And with that, we have our own react environment made by us! If you have any problem or questions don't doubt in leave a comment. Thank you for read!