Thursday, November 24, 2022

React create-react-app Project Structure

In the post Creating a New React Project - create-react-app we saw how to create a React project and how to run the default app which is already generated. If you are wondering what all happened internally to bootstrap your application and how did you get that display that's what is explained in this post

create react app

React project structure in detail

Let's start with understanding the React project structure as generated by using create-react-app.

Initial React project structure as created by create-react-app should look like as given below.

React Project Structure

node_modules- This folder contains all the external modules that are needed in your project. The modules or libraries you import in your project should be present inside the node_modules folder.

public- This folder has the most important file- index.html. This is the file browser will display. Another file manifest.json provides metadata about the project like project name, icons which are used, thems and colors.

src- This is the folder that contains our source code for the created app. This is the folder which you will use the most to create components for your React app.

package.json- Lists all the project dependencies with the version. Also lists the scrips that we use to run our app.

README.md- This file lists many useful commands that you can use to run your app and links to some resources about create-react-app.

Running the app (Internal flow)

Once the project is created you can run the app using npm start command. After the server has started you can open http://localhost:3000 in your browser to view the application.

Let's try to understand how do you come to this view which is displayed in the browser.

As already stated, it is the public\index.html which is the starting point of the application. If you inspect the code in index.html you will find one <div> element with id as “root”. It is this <div> where your code will be injected.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <!--
      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>

Now, the next thing is how does React know that it has to inject code with in the <div> element with id as root. For that it refers src\index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

ReactDOM.createRoot lets you create a root using the browser DOM node specified as argument. Here the argument is document.getElementById('root') which connects this index.js with index.html.

React renders the App component and the nested components inside root.

root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

src\App.js has the code that is rendered.

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

You may have a question how does React know that starting point is index.html and index.js. For that you will have to refer node_modules\react-scripts\config\webpack.config.js which is a configuration file referred by Webpack while bundling the app.

In your React app you may have a number of different types of files (js, css, html) which are "bundled" using tools like Webpack, Rollup or Browserify. Bundling is the process of merging all the files into a single file (bundle.js). This bundle can then be included on a webpage to load an entire app at once. This helps in optimizing the code and increases app performance.

In this configuration file (webpack.config.js) you will find an entry-

// These are the "entry points" to our application.
// This means they will be the "root" imports that are included in JS bundle.
entry: paths.appIndexJs,

Configuration for the mentioned paths is specified in Paths.js file which is at the same location as webpack.config.js. One of the entries in Paths.js is

appIndexJs: c(resolveApp, 'src/index')

The above entry resolves to index.js and that's how the entry point is known.

If you search "index.html" in webpack.config.js you will find a plugin configuration as copied below.

plugins: [
      // Generates an `index.html` file with the <script> injected.
      new HtmlWebpackPlugin(
        Object.assign(
          {},
          {
            inject: true,
            template: paths.appHtml,
          },

In one of the comments in index.html you may see this line-

The build step will place the bundled scripts into the <body> tag.

Which means at run time index.html is re-generated with scripts places into it and that is the file which is actually rendered.

That's all for this topic React create-react-app Project Structure. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. JSX in React
  2. React HelloWorld App - First React App

You may also like-

  1. Angular Project Structure With File Description
  2. Creating New Component in Angular
  3. Installing Docker on Windows
  4. How to Convert Date to String in Java

No comments:

Post a Comment