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 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 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:
Let's start configuring our webpack. Inside webpack.config.js
let's add the next code:
.\reactenv\webpack.config.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
<!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
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
"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á
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
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
"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
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.
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!
Top comments (1)
hi thanks for tutorial
i can not use c++ in react is it possible to guide
i would appreciate if you could