Say Bye to create react app. Here's how to Build your react project from scratch with webpack and Babel. 
Tags: javascript, react, beginners, tutorial
Published: 2020-02-29 21:45:43

The memory of my first react app is still fresh in my memory. I can remember how ridiculously easy it was to set up a new project. Oh! My beloved `npx create-react-app myAwesomeApp`. 


But as I go deeper into front end Development, I learned that CRA has many limitations. Don't get me wrong, CRA is an amazing tool which I still use. But its lack of flexibility made me  look for other alternatives.



There are different ways to set a react project without CRA, but in this article, I will show you how to set up a react project using [webpack](https://webpack.js.org) and [Babel](https://babeljs.io). 

###What is webpack and Babel? 

Basically, [webpack](https://webpack.js.org) is a javascript bundler that bundles your static assets into one big file. [Babel](https://babeljs.io) is a transcompiler that converts ES6 Javascript to an older version (typically, ES5) of javascript for compatibility on all browsers. 

Even though I won't be going deep into the aforementioned tools, I really recommend that you checkout their respective docs before proceeding. 

Let's get started! 

I am a big fan of yarn, so that's what I will be using throughout this tutorial. 

### let's create and go into our project folder.

```javascript
Mkdir react-boiler-plate
 Cd react-boiler-plate
```

We'll be installing packages, so let's create a package.json file

```javascript
Yarn init -y

```
Running this will create a package.json file that will contain the info of our app and all its dependencies.

Before installing any package, let's start by laying the structure of our app. This of course will be simple, nothing complicated.

```
react-boiler-plate 
 public
 Src
 Package.json
```
Here we have two empty folders and a package.json. Does this structure ring a bell? Yeah, we will be mimicking  the structure of our beloved CRA. 

Now let's add some packages. We'll start with the dependencies. 

```javascript
Yarn add react react-dom

```
These packages are the only required dependencies  

Let's install the dev dependencies. I will be breaking this into two parts— the webpack packages and the Babel package. 

```javascript

Yarn add --dev webpack webpack-cli webpack-dev-server html-webpack-plugin

```
Tip: the --dev flag is similar to --save-dev in npm

Let's get over each package. 

The first package is webpack for assets bundling, webpack-cli will let us use webpack cli. Remember ```yarn start``` or ```npm start```  in create-react-app ? Webpack-dev-server gives us a development server. It comes with many things include hot reloading, that's for later. 



Let's move on to installing Babel.

```javascript

Yarn add --dev @babel/core @babel/preset-react @babel/preset-env babel-loader style-loader css-loader

```
So we've installed Babel preset for both react and the environment (browser), style loaders to handle the importation of our assets and Babel loader for our .js files.

Next, let's create two files in our root directory.

``` 
touch webpack.config.js .babelrc

```
our project structure should look like this

```
-react-boiler-plate
  public
  src
  .babelrc
  webpack.config.js
  package.json
```

In our webpack.config.js file, let add some code. There's lots of different ways to write your webpack config and it all depends on your preference. I will stick to my convention in this article. 

First, we're gonna need to require two packages. One is the path Module that comes with node and the other one is html-webpack-plugin, the package  we installed. 

```javascript
const path = require('path')
const HTMLplugin = require('html-webpack-plugin')

```
Now let's set up our rules. This will be an array of objects. The objects is for each rule we want to set. In this project, there will be only two rules.  You can add as many rules as you want depending on your needs and project.
This is one of the many reasons as to why I like webpack — flexibility. 


```javascript
const rules = [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'

   }
},

{
test: /\.css$/,
exclude: /node_modules/,
use: ["style-loader", "css-loader"]
}


]

```
The first object, We're telling webpack to use babel-loader on all .js files in our project, but we exclude the node_modules file. 
This is also the case in the second object. We tell webpack to use our style loaders on our .css files. 

Next let's export our config. 

```javascript
module.exports ={
entry: path.join(__dirname, 'src' 'index.js'),
Output: {
filename: 'bundle.js',
Path: path.resolve(__dirname, './build')

},
module: {rules},
plugins: [
    new HTMLwebpackplugin({
      template: './public/index.html'
    })
}
```
Here, we specify our entry and output file. The entry  file is not created yet, obviously. This file is similar to the index.js file in create-react-app.
The output file is where our bundled app will be created. We specify the name to bundle.js and the parent folder to build. 

The module key is where we set our rules. I see many people put their rules hers, but i like to just put it in a constant and then call it here. It makes everything cleaner. 
Since we have already done that we can just do ```module:{rules: rules} or module:{rules} (ES6)```.


Lastly, the plugins  key contains an array of all the plugins we want to use. There are many plugins which you can use in your projects. Here is a [list](https://github.com/webpack/docs/wiki/list-of-pluginss) of some.


Our webpack.config.js file should look like this:

```javascript

const path = require('path')

const HTMLplugin = require('html-webpack-plugin')

const rules = [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'

   }
},

{
test: /\.css$/,
exclude: /node_modules/,
use: ["style-loader", "css-loader"]
}


]

module.exports ={
entry: path.join(__dirname, 'src' 'index.js'),
Output: {
filename: 'bundle.js',
Path: path.resolve(__dirname, './build')

},
module: {rules},
plugins: [
    new HTMLwebpackplugin({
      template: './public/index.html'
    })
]
}

```

Before we forget, let's  create the files we specified above. The index.html in the public folder and the index.js file in the src folder.

Our project structure should look like this:


```
— react-boiler-plate
 public
   index.html
 src
   index.js
 .babelrc
 webpack.config.js
 package.json

```

Next, Let's configure babel. In our .babelrc file, add the presets  we installed earlier. The content of this file should be in JSON format.

```javascript

"presets"["@babel/preset-env","@babel/preset-react"]

```

We have finished setting up our react project — well, 90% of it. In our index.html file, let's add a simple html boilerplate. if you are using vscode, type the exclamation mark and press enter. This will auto generate a HTML document for you. Then add an empty div with the ID of root and save. 

Our index.html should look like this

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <title>React boilerplate</title>
</head>
<body>
    <div id='root'></div>
</body>
</html>

```

Next, let's go to our index.js file in the SRC folder. First we need to 


Import React and ReactDom. After that, Let's create a constant that will store the  div that we created in our index.html file. 
 Our file should look like this: 
```javascript
import React from 'react'
import ReactDom from 'react-dom'

const  root  = document.getElementById('root')
``` 

In the index.js file, let's create a functional component called app and wrap up.

Now our index.js should look like this: 

```javascript
 
import React from 'react'
import ReactDom from 'react-dom'

const  root  = document.getElementById('root')

const App = () => {
return (
<h1>Hello from React</h1>
)

} 


ReactDom.render(<App />, root)

```


Voila! our react project is completed — mostly. 

Remember how we use to start a dev server and build our app in a create-react project? ```yarn start``` ```yarn build```

webpack-dev-server is an amazing tool that let us do just that. we can create our script, customize how our server should run, also offers hot reloading. You can check  out the official documentation [here](https://webpack.js.org/configuration/dev-server/)

So let's head to package.json to set up our scripts. Since we won't be doing any testing and ejecting, we only need two scripts for this projects — start to start the dev server and build to compile our app. 

In the package.json file, add a new key,scripts, with an object value. Inside the object, add the following code. 

```
"start": "webpack-dev-server --mode development  --open --hot",
 "build": "webpack --mode production"

```
What we added in the package.json file should look like this: 

```json
"scripts": {
    "start": "webpack-dev-server --mode development  --open --hot",
    "build": "webpack --mode production"
  }
```

save and exit.

##Voila! 
Our react project is now complete.

```yarn start``` will start the development server. And if everything is okay, We should see a "hello from react in our" browser. 


I know that is a long one, perhaps too long. you can use this as a boilerplate for all your react projects. You can also customize it and add more functionalities and rules. 

If you're relatively new to webpack, i recommend you to learn more about it. It's a handy tool that you can't live without it (at least in my case).

The whole project is available on my github repo. You can check it out [here](https://github.com/kraken-coder/react-app-skelaton)