DEV Community

Amir Ghezala
Amir Ghezala

Posted on

Understanding the React build workflow and the folder structure


React is an open-source JavaScript library that is used to form user interfaces. In this article we tend to discuss what it takes to build a React application on our local machine and understand all the folders and files that comes with the create react app tool.
Building a React project on our machine requires an elaborate workflow whether it is a single page or a multipage application. So an important question that should be asked is:

Why it is necessary to have this workflow and how to compose it?

Lets tackle the why part of the question first:

  • We have to optimize our code. For React application we have to be able to generate an optimized small code in order to increase the performance of the application. 
  • Another important reason is to be able to benefit from using next-generation JavaScript features. JavaScript is evolving and the language has from time to time new features that are not immediately supported in all browsers. Having a tool like babel allows us to use those features immediately, since its responsible to translate our code to a code that is supported by the browsers we target.
  • A third reason concerns productivity. The CSS auto-prefixing in the next-generation JavaScript features allow us to reach a maximum browser support for CSS features. If we try to add them manually it would be a real hassle.
  • Another aspect of productivity is the provided tool linter. Acquiring a linter in our code IDE will save us time to find an error before the execution of the code. The below code illustrates how a linter works. 

The above are the main reasons we need a workflow.
Now let's see how to achieve it:

  • The first thing is to have a dependency management tool. Dependencies are third party libraries. React, React DOM and every built tool that we will eventually use are dependencies. NPM (node's package manager) is a recommended built tool to use as it manages packages and dependencies.
  • Next to a dependency management tool a bundler is used to produce modular code. By modular, we mean the code will be divided over multiple files and each file has its own function and specialty. 

Webpack is an example of a bundler that has a great advantage when it comes to eventually sending the divided files to browsers because some of these web browsers might not support the divided files and if they do, we cant just send all requests to these specialized files.

  • Lastly, we need a server to test our project on our local machine. This really looks complex.  Fortunately, React team came up with a tool that can create an app supporting all what we mentioned above without configuration from us. It is maintained by Facebook and its community.  The tools is Create React app. You can find the installation instructions here. > Just an important notice, after installation leave the NPM start process running. So whenever we change something in our code it will automatically reflects the changes. After setting up the project we will all have the same amount of created folders and files. # Now let us discuss the most important folders and files. Starting with the package.json file that has the general dependencies of our project.
{
  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-scripts": "3.0.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

As you notice we have three dependencies in this project created by create React app.
You can also see that we obviously import React. Here we are using:
Latest version of React at the time I am writing the article.
ReactDOM: provides DOM-specific methods. We will only use the "render" method of the module in index.js to render our application in the DOM.

  • Latest version of React at the time I am writing the article.
  • ReactDOM: provides DOM-specific methods. We will only use the "render" method of the module in index.js to render our application in the DOM.  React Scripts: a package that has scripts and configurations used to provide all what we mentioned about the build workflow including development server and the next generation javaScript feature support which we use in the project.

The node_modules folder :

It has all the dependencies and sub-dependencies of our project.
In the package.json file we discussed only three dependencies including React, React DOM and React Scripts. More specifically, React Scripts have a lot of other dependencies made up of all the build tools that compiled the code and so on. You shouldn't modify anything in the node_modules folder.
The public folder:

An interesting one, it's the root folder that gets dealt by the web server in the end. In this folder we have one significant file which is the index.html file. This file has a normal html page and it is the single html page in our project.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

So this is the single page, where in the end our script files will get instilled by that build workflow. We can modify this file but we won't add any HTML code here.
I want to highlight this div here with the ID root: 
<div id="root"></div>
It important because here where we will place our React application later.
In the HTML file you can import libraries such as CSS libraries and add meta tags. 
Getting to manifest.json file:

 

{
  "short_name": "React App",
  "name": "Create React App Sample",
  "icons": [
    {
      "src": "favicon.ico",
      "sizes": "64x64 32x32 24x24 16x16",
      "type": "image/x-icon"
    }
  ],
  "start_url": ".",
  "display": "standalone",
  "theme_color": "#000000",
  "background_color": "#ffffff"
}
Enter fullscreen mode Exit fullscreen mode

This info gives information to the browser about your application. For example, this is required for mobile browsers so that you can add a shortcut to your web application.
Another interesting folder is the src folder:

It possesses the files that we are going to work in which is the actual react application.
It has the index.js file:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
Enter fullscreen mode Exit fullscreen mode

This file access the root element in our DOM , the element with id root in our HTML file.

ReactDOM.render(<App />, document.getElementById('root'));
As you notice it renders our React application with the render method. Also there is a reference of App object that we imported from the App file.
import App from './App';
The extension .js (App.js) is omitted because it is automatically addressed by our build workflow. 
Lets take a look at our App.js file:

import React from "react";
import logo from "./logo.svg";
import "./App.css";
function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}
export default App;
Enter fullscreen mode Exit fullscreen mode

Here we can see our first and only React component we have in the starting project.
Another file to mention is the App.css:

.App {
  text-align: center;
}
.App-logo {
  animation: App-logo-spin infinite 20s linear;
  height: 40vmin;
  pointer-events: none;
}
.App-header {
  background-color: #282c34;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: white;
}
.App-link {
  color: #61dafb;
}
@keyframes App-logo-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
Enter fullscreen mode Exit fullscreen mode

This file determines some styling we use in the App.js. However, the CSS styling does not only relates to the App.js file, it is global styling.
We also have an index.css file:

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
    "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
    monospace;
}
Enter fullscreen mode Exit fullscreen mode

This file implements global styling and everything that should be used for some general set up as we can see here for the body of our application.
The registerServiceWorker.js file is essential to register a service worker. It pre-cash our script files and there is no obligation to configure anything there. You can also safely delete this file if you don't know or don't care about service workers.
Lastly the App.test.js file:

import React from 'react';
import logo from './logo.svg';
import './App.css';
function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}
export default App;
Enter fullscreen mode Exit fullscreen mode

Essentially, it allows us to create unit tests for different components in our application.

To conclude, any programmer wants to code in an efficient way where he can avoid manual interference to create a convenient environment for coding. Having a build workflow is really important when it comes to building big React projects. Can you imagine having to learn every single one of these tools before being able to do anything in React? 
Fortunately, the create react app tool made it more easier.

Did this article help you demystify the files and folders that come with create-react-app? Let me know in the comments section.

Happy React coding!

Top comments (0)