Building the React Scaffolding from scratch
Tags: react, babel, beginners
Published: 2020-08-18 03:52:00

---
title: Building the React Scaffolding from scratch
published: true
description: Understanding what 'create-react-app' does
tags: #React #Babel #Beginner
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/l8lbuslyxzeb5e5tkq1t.jpeg
---

Welcome, Fam!

While I originally planned to do a fair bit more blogging it's been a roller-coaster ride the last 6 months, stepping into the C# world spending some time with a company working on an older asp.net application.

As I find myself gravitating back to React, I realised 🤔... I'd forgotten so much! and since I dropped off just before Hooks became so stable/adopted, I recognized very little JSX code anymore.

So back on the horse I go! but this time if I was going back to the start it wasn't going to be from 'create-react-app' scaffolding, I wanted to level up my knowledge and learn from the ground up.

And I felt it was worth a blog, so if you are relatively new to React or haven't built a project from scratch this article might be for you.

The most surprising part really is just how easy this was!

---
### Setting up the folder structure and web-server.

First off we need to create a few folders and get the HTML file running with the web-server.

I like to get this running and make sure there aren't any critical issues (I try and identify known issues early and weed them out).

In the root project create a Public file and an HTML document, this will be the entry point for our React app.

But while we're at it, I like to just create the skeleton structure (and if you've started a react app before it should be pretty familiar).

```
	<!-- Folder Structure -->

root-folder/
	├── public/
	│   ├── scripts/
	│   │   └── app.js
	│   └── index.html
	└── src
        └── app.js

```

Once that is done add your basic HTML page, my emmet creates this for me automatically if I start an empty HTML page with the character '!', but if you don't have the emmet plugin it should look something like this (get emmet too).

```
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
</head>
<body>
	
</body>
</html>
```

There are two more things required in the HTML page to get React to run (ok so three), the script tags in the body, and the div attribute that acts as the injection point.

In the body add a div with an id attribute of "app", the two unpkg.com script links in Part 2 of the [React instructions](https://reactjs.org/docs/add-react-to-a-website.html) page, and finally a script tag with a source that points to the app.js in the scripts folder.

But before we run off, above the div with the id of 'app' and just for testing purposes add some text in that body so that we know everything is working when the page loads.

So your body should look like this...
```
<body>
    Test Text
    <div id="app"></div>
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
   <script src="/scripts/app.js"></script>
</body>
```

Head back to your command line and while **ensuring you are pointing to the root folder**, we want to kick-off our packages.

Now I am using Yarn in this instance, basically, as I have always used NPM I wanted to try something a bit different, but all commands can easily be replicated in NPM.

```
    $ yarn global add live-server
```

const postScript = (hol-up-a-min moment) => { 
Yes, I am aware there is a live server extension in VS Code, but I am backing up and going manual right now.  The point of manually creating what can be done in scaffolding is to get a better understanding of how things work at the root level.
return 'Back to the regular program'
}

After I install something with Yarn/NPM I always like to check installs properly with a package version check, for live-server it's

```
    $ live-server -v
```

This will give you the version number, or an error, and I'd rather locate the error now than have to debug and find it later.

Now to kick off live-server and see our HTML page simply run live-server and the target folder, in my case

```
    live-server public
```

This will find the index.html page and whatever you wrote in the body will display as text on the page.

SUCCESS, we have our live-server setup (you are now free to remove the Test Text from the page).

---
### Babel + JSX

If you aren't aware of [Babel](https://babeljs.io/) or what it does, that's OK we're all here to learn (and tbh I only knew OF it before I went down this lesson too).

Babel is a JavaScript compiler that React uses to compile JSX down to browser-friendly JavaScript.

const postScript = (hol-up-a-min moment) => { 
I am assuming you know what [JSX](https://reactjs.org/docs/introducing-jsx.html) is and I wasn't planning on covering that here, if not it's a JavaScript Syntax Extension that I like to call ReactScript it's a combination of JS+XML.
}

So let's add see what Babel does by adding some JSX, in the script/app.js file we need to add 3 things.

1. JSX
2. The document element: this is the div in our HTML page that react uses as the injection point.
3. ReactDOM.render(): is the method that takes our JSX code and the HTML injection point and creates the magic, more info can be found [here](https://reactjs.org/docs/react-dom.html#render).

```
    const template = (
	<div>
		<h1>React from Scratch</h1>
		<p>Thanks for reading my article</p>
	</div>
    );

    const appRoot = document.getElementById("app");

    ReactDOM.render(template, appRoot);
```

Making sure live-server is running, what happens without Babel?

![React without Babel](https://dev-to-uploads.s3.amazonaws.com/i/8lyw7fwksm91i9gsza11.png)

This doesn't give us much of an explanation, but basically what's happening, is the browser is unable to decypher the JSX encryption.

So let's add Babel!
```
    $ yarn global add babel-cli
```
And check the install just to be sure
```
    $ babel --version
```

Next, the project needs to be initialised, so run the init command and cycle through the project initiation questions (I'm also assuming I don't need to explain this process).
```
    $ yarn init

    name (application name):
    version (1.0.0):
    description:
    entry point (index.js):
    repository URL:
    author:
    license (MIT):
```
This will generate your package.json file.

Then we need to install the two Babel packages that will convert the JSX

1. [babel-preset-react](https://babeljs.io/docs/en/babel-preset-react): As the title suggests, this is the React specific extension.
2. [babel-preset-env](https://babeljs.io/docs/en/babel-preset-env): env is the magic that manages which type of JavaScript the JSX gets compiled down to, so the magic basically.

Add these with:
```
    $ yarn add babel-preset-react babel-preset-env
```
Once you see that's completed your folder structure should now look like this.

```
root-folder/
	├── node_modules
	├── public/
	│   ├── scripts/
	│   │   └── app.js
	│   └── index.html
	├── src
	│   └── app.js
	├── package.json
	└── yarn.lock
```

---
### Running the project

Finally, we need to invoke Babel.

Grab all the code that is in the scripts/app.js folder and move that to src/app.js, the reason for this is src/app.js is where we write all the JSX and the scripts/app.js folder is where Babel compiles the readable JavaScript to that gets injected into the HTML.

In a new Command Window pointed to the project root folder (leave live-server running in another), we need to invoke summon that Babel magic with 3 inputs (and one option to make your life easier)

1. The JSX file that needs to be read (src/app.js).
2. The out file where babel compiles the JS to (public/scripts/app.js).
3. The presets required (env + react).
4. A watch flag to refresh the page on each save (--watch)

These commands according to my file structure, would look like this:
```
    $ babel src/app.js --out-file=public/scripts/app.js --presets=env,react --watch
```

With this, we have now created the (basic) boilerplate of a React app, from here it's up to you to create and add the packages as you go along.

---

Well, I'll leave it there short and sweet! 

Next steps will involve adding webpack later down the road and I'm sure there'll be a blog on that too!

Signing off for now...

Cooper 🍕 🍺 🍔 🍶