How to create a react app without create-react-app command
Tags: react, webpack, babel, npm
Published: 2020-05-18 00:39:38

## Create a react app only using a basic webpack and babel configuration

You can find the code with the settings already made in my repository https://github.com/jose1897/minimal-react-webpack-babel-setup
### Requirements
* install node

First we will define the tools that we are going to use and we are going to give a brief review of what each one does

### Webpack

Webpack is a Bundler of javascript modules although it can also transform static files such as HTML, css and images.

The main benefits of using webpack are:

* Provides you with a transcompiler with babel
* Elimination of dead code
* Code minification
* Management of static files

### Babel

It is a javascript transcompiler that is mainly used to convert ECMAScript 2015+ code to a compatible javascript version for older environments.

## Already finished the boring theory part 😴 Let's start with the configuration

We will start by creating a new directory that will contain our project

```bash
mkdir react_app
cd react_app
```
Then we will proceed to start a new project using npm
```bash
npm init -y
```
This will create a `package.json` file which has the default settings for an npm project.

Before continuing to install the packages we are going to create the basic files of the project
```markdown
react_app
├─ package.json
└─ src
   ├─ App.jsx
   ├─ index.html
   └─ index.js
```
The file `index.html` and` index.js` will be the ones that will start our project. For now, let's work with them.

The `index.html` will have the basic HTML5 format with a div tag that will have the id 'root'
```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>React App</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>
```
This div will be where our react components will be rendered

The `index.js` will start the javascript script in the html

But before writing the code of this file we will install react with the following command
```bash
npm install react react-dom
```
These packages allow you to write react code and render it at the DOM

Now we can code the `index.js`
```jsx
import React from 'react'
import ReactDOM from 'react-dom'

ReactDOM.render(<h1>Hello world</h1>, document.querySelector('#root'))
```
Import the react packages and render an h1 in the tag with the id of 'root'

### Now we continue with the setup! 😁 

We will install the main packages for the configuration using npm
```bash
npm install  webpack webpack-cli --save-dev
npm install @babel/core @babel/preset-env @babel/preset-react babel-loader --save-dev
```
Ok ok I know, this is too much at once but everything will be explained

The webpack packages are the basic packages so that we can use to bundle the project code

Babel packages, I will detail them one by one

* **babel/core:** is the babel core package
* **@babel/preset-env:** allows you to use the latest JavaScript without micromanaging which syntaxist transformations
* **@babel/preset-react:** allows to use react code
* **babel-loader:** This package allows you to transpile JavaScript files using Babel and webpack.

Now that we understand what each package is used for, let's add the following scripts to `package.json`
```json
"start": "webpack --mode development",
"build": "webpack --mode production"
```
You will notice that when executing any of these scripts we have errors and not exactly the expected result, this is because we have not configured the webpack even so we are going to do it

To configure webpack we will create a file `webpack.config.js`
```js
const path = require("path");

module.exports = {
  entry: "./src",
  output: {
    path: path.resolve(__dirname, "public"),
    filename: "bundle.js",
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)/,
        exclude: /node_modules/,
        use: ["babel-loader"],
      },
    ],
  },
  resolve: {
    extensions: ["*", ".js", ".jsx"],
  },
};
```
Ok, don't be scared. What we are doing here is very simple.

We export the webpack configuration, first indicating where is the `index.js` file that we are going to use and then indicating the folder where we are going to save it and the name of the file.

Then we create a rule indicating webpack for the .js and .jsx files is going to use babel-loader

And finally we indicate the extensions that webpack can use

### What's going on? still not working 😟

Well that's because we haven't configured babel yet, for this we will create a `.babelrc` file
```json
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "node": "current"
        }
      }
    ],
    "@babel/react"
  ]
}
```
Here we are only indicating to babel to use the packages that you had installed before specifying that we will use the node modules for the preset-env

### It works now! ...Or not ?

Well, you can certainly run the scripts and the bundle.js file will be created correctly, but there is no html to open our page. And that's because webpack is designed for javascript, to be able to use it with html we will have to install a plugin we will use npm for this
```bash
npm install html-webpack-plugin --save-dev
```
We will add this plugin to our webpack configuration
```jsx
const path = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin');

const htmlPlugin = new HtmlWebpackPlugin({
  template: "./src/index.html",
  filename: "./index.html"
})

module.exports = {
  entry: "./src",
  output: {
    path: path.resolve(__dirname, "public"),
    filename: "bundle.js",
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)/,
        exclude: /node_modules/,
        use: ["babel-loader"],
      },
    ],
  },
  resolve: {
    extensions: ["*", ".js", ".jsx"],
  },
  plugins: [htmlPlugin]
};
```
First we import the plugin we instantiate it indicating which file it will take and the name of the file it will create and then we include the instance in plugins

### Everything is ready !! 😉 Well almost

The `index.html` and the` bundle.js` are already created when running `npm start` or` npm run build` but this is not how a react application is executed, at least not in development mode, it is annoying that every once we make a change in the code we have to create the files and for this we will add a new webpack package using npm
```bash
npm install webpack-dev-server
```
Now we will change the start script of the `package.json`
```
"webpack-dev-server --mode development --open --hot --port 3000" 
```
This command will no longer create the files in the `public` folder instead it will start a server at [http: // localhost: 3000 /] (http: // localhost: 3000 /)

The —open indicates that the webpack will continue to run by compiling the file changes and making these changes visible

The —hot is for changes to be made without having to refresh the entire page

## Now your setup is ready!
Let's add code to the `App.jsx` file to test that you can also run this extension file
```jsx
import React from 'react'

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

export default App
```
And let's import this into `index.js`
```js
import React from 'react'
import ReactDOM from 'react-dom'

import App from './App'

ReactDOM.render(<App/>, document.querySelector('#root'))
```
### That was all any questions or suggestions you can leave in the comments I am just a student and what interests me most is learning so do not hesitate to comment