React App From Scratch
Tags: react, webpack, javascript, webdev
Published: 2020-09-26 01:01:35


There are several ways of starting a React App, the most popular and easy being [create-react-app](https://github.com/facebook/create-react-app), and [Gatsby](https://www.gatsbyjs.org/) for static pages. These tools let you build a React application with no extra configuration, but at a cost:

 > Usually you wouldn't know what is happening behind the scenes.

And if you want a more fledged application you will need to tweak almost every part of the configuration.

## **The I'm more of a code type of person**

[The github repo](https://github.com/markhker/react-from-scratch/tree/basic)

## **Start Simple**

In this tutorial I assume you have basic knowledge of JavaScript, bash commands, git, node and npm/[yarn](https://yarnpkg.com/) installed. I will use yarn for all the examples, but you could change them for npm commands.

Let's start with a simple configuration, including only the React package, Babel for transformations and Webpack to handle the bundle.

To get started let's create a new directory for your React Application and move in:

```shell
mkdir react-from-scratch && cd $\_
```

Initialize your project and create a minimal folder structure, use the -y option in yarn to skip the init questions:

```shell
yarn init -y
```

```shell
git init
```

## **Install dependencies**

With the next commands you will install the dependencies and the development-only dependencies needed to start developing your React app:

```shell
yarn add react react-dom
```

```shell
yarn add -D @babel/{core,preset-{env,react}} babel-loader webpack{,-cli,-dev-server} html-webpack-plugin
```

In the above command we are using brace expansion as shortcut to install npm packages with similar names at once, the same as:

```shell
yarn add -D @babel/core @babel/preset-env @babel/preset-react babel-loader webpack webpack-cli webpack-dev-server html-webpack-plugin
```

With React, we will use modern ECMAScript features that older browsers don't understand, that's why we need to transform our code. This transformation is "transpilling" and it's executed through a webpack loader. A webpack loader is a translator so webpack can understand what type of code you're using e.g: ECMAScript, css, html, etc.

Each package serves a purpose:

- **react:** Well, you know what React is. (Do you?)
- **react-dom:** For rendering React components into the DOM
- **webpack:** It's the bundler, that packages our code for production use
- **webpack-dev-server:** It's a simple web server that provides us live reloading
- **html-webpack-plugin:** Simplifies creating and using HTML files to serve our webpack bundles in the browser
- **@babel/core:** The main package used to convert ECMAScript 2015+ into backwards compatible code
- **@babel-preset-env:** A predefined configuration for converting modern JavaScript into more compatible code
- **@babel-preset-react:** Configuration and plugins for transforming JSX and other React-specific code to JavaScript
- **babel-loader:** The translator webpack will use to bundle our code

# **Setup your files**

First we will need "support" files, or configuration files. The ones that will let our application know what it is and how it needs to be interpreted.

First our babel configuration file (.babelrc):

```json
{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ]
}
```

We include our earlier installed presets to let know babel what we want it to do with our code. We are telling babel: "I will write some JavaScript from the future and some React components. And I want you to transform it to a backwards compatible version of JavaScript. Thank You"

You need an HTML index file to load the JavaScript on the browser (index.html):

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>React From Scratch</title>
  </head>
  <body>
    <!-- Prompt a message in the browser if users disabled JS -->
    <noscript>Your browser does not support JavaScript!</noscript>
    <div id="root"></div>
  </body>
</html>
```

This will provide an entry point for webpack, to attach our main JavaScript bundle to the DOM.

Next we will write (or copy/paste) our webpack config file (webpack.config.js):

```js
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      }
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: 'index.html'
    }),
  ],
}
```

The minimal configuration we need to transform our React app. Here we are telling webpack to pipe every file with the .js or .jsx extension through the babel-loader translator. And pointing to the main html file we want to use as a template.

You can know more of webpack on [their documentation.](https://webpack.js.org/concepts/)

You need a React entry file, you will call this index.js (src/index.js):

```jsx
import React from 'react'
import ReactDOM from 'react-dom'

const App = () => <div>Hello there!!</div>

ReactDOM.render(<App />, document.getElementById('root'))
```

This is the entry point of your application, the root. From here you will be calling the rest of the code necessary for you app. And must be inside your src folder.

And we will need to add a few scripts to our package.json file:

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

Then you can run `yarn start` to start the development server and see the changes on your browser. This should open a tab on your default browser, if not, go to `http://localhost:8080` to see your application.

When you want to build a production package you run `yarn build`. And you can see you final static assets on the `dist` folder.

With this you have the basic configuration to start developing you app. But one of the main benefits of starting a React project from scratch is that you can expand your configuration to increase its features.

In the next post I'll explain how to add tried methods for a more professional application, including:

- Advanced Composing Configuration
- Tree Shaking
- Minification and Optimization
- Source Mapping
- Linting and Prettifying
- Import Aliases
- Environment Variables
- Bundle Analyzing
- Hot Module Replacement
- Code Splitting
- Lazy Loading
- Basic Routing
- CSS in JS
- Assets loading

[Share this on Twitter](https://twitter.com/intent/tweet?url=https%3A%2F%2Fmarlom.dev%2Freact-app-from-scratch)