An Overview of the create-react-app File and Folder Structure
create-react-app creates a series of files and folders as it instantiates and creates a Webpack bundled React application. In this lesson, we'll spend some time addressing and highlighting each of the files and folders scaffolded by create-react-app.
Create React App - The Rundown#
📝 This lesson's quiz can be found - here.
🗒️ Solutions for this lesson's quiz can be found - here.
create-react-app
creates a series of files and folders as it instantiates and creates a Webpack bundled React application. For those who may be unfamiliar with the scaffold created from create-react-app
, we'll spend this lesson going through the generated client/
application.
create-react-app
has created an application scaffold that looks like the following:
client/
node_modules/
public/
src/
.gitignore
package-lock.json
package.json
README.md
tsconfig.json
node_modules/
#
The node_modules/
directory in our application refers to all the different JavaScript libraries that have been installed in our application.
public/
#
public/index.html
#
The public/
folder holds the favicon asset as well as the root markup page of the application - the index.html
file. When we take a look at the public/index.html
file, we can see a simple HTML file that contains a <head>
element and a <body>
element. The <head>
tag specifies standard viewport settings and references the favicon asset in the public/
folder.
<!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>
<!-- -->
</body>
</html>
In the <head>
tag of our public/index.html
file, we can see some documentation and use of a manifest.json
file. A manifest JSON file helps provide metadata for when an app is installed on a user’s mobile device, which makes a web application more progressive and is set up in the public/manifest.json
file of our app. This ties into some of the boilerplate code create-react-app
gives us to help create a Progressive Web Application.
Some comments exist in the <head>
tag that tells us how the PUBLIC_URL
tag behaves. In the create-react-app
setting, PUBLIC_URL
is replaced with the URL of the public folder during build which helps reference assets within the public/
folder. We won't be making any changes to the public/index.html
file except for renaming the title of our application to the name of our app - TinyHouse
.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- -->
<title>TinyHouse</title>
</head>
<body>
<!-- -->
</body>
</html>
In the <body>
element of the public/index.html
file, we’re presented with a <noscript>
tag followed by the <div id="root"></div>
element.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- -->
</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>
The content within <noscript>
is displayed to the user when the user has disabled scripts in the browser or is using a browser that has an unsupported script. The <div>
element with the id
of root
is where our entire React application will be mounted onto. This is the element that’s referenced in our React render()
function with which we’ll see shortly. Finally, we have some comments in the <body>
element that tells us upon building the application, the bundled scripts of our app will be placed into this <body>
tag.
src/
#
We’ll hardly find the need to be making any significant change in the surrounding files that involve the set up of our application. The vast majority of the time, we'll be working within the src/
directory that contains the TypeScript, React, and CSS files that we’ll be working directly with.
src/index.tsx
#
The src/index.tsx
file is the root React/TypeScript file in our application. If you’ve never used TypeScript and React before, the .tsx
file extension may seem new to you. JSX (or otherwise known as JavaScript XML) is an extension that allows us to write JavaScript that looks like HTML.
We can see the use of JSX in the ReactDOM.render()
function where the first argument being passed is the <App />
component.
ReactDOM.render(<App />, document.getElementById("root"));
The declaration of <App />
in the render()
function is JSX - XML-like syntax in our JavaScript file. In standard React, we’re able to use JSX within files that have the normal .js
file extension though certain people prefer to use the .jsx
file extension to denote the React JavaScript files that contain JSX.
If we intend on using JSX within our TypeScript files, we must name our files with the .tsx
file extension. The other requirement to using JSX in TypeScript is to have the jsx
option enabled in our TypeScript configuration, which we’ll see has already been done in our client project's tsconfig.json
file.
The ReactDOM.render()
function helps render the parent <App />
component on the root element in our public/index.html
file. The render function is from the ReactDOM
library and takes up to three arguments with which the first two is often defined. The first argument is essentially the root level element we'd like our React application to render (which is currently the <App />
component). The second argument is where to render (i.e. mount) it with which in this case is the reference to the DOM node with the id
of root
.
The third argument of the render()
function takes a callback function that when provided runs the callback after the component is mounted or updated. We won't need to run this callback function so we won't introduce it. The only change we'll make is more of a preference - instead of importing the ReactDOM
global, we can directly import the render()
function that's also being exported from the react-dom
library.
Our src/index.tsx
file will then look like the following:
import React from "react";
import { render } from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
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();
At the end of the src/index.ts
file, there's exists an additional reference to help in the introduction of a service worker. Service workers are scripts that run in the browser to help applications be more progressive by introducing features like asset caching and push notifications. We’re not going to spend much time in this course explaining how service workers and Progressive Web Apps behave, so we'll leave this in its current state for now which is essentially the unregistered state of the service worker defined in the src/service-worker.ts
file.
src/react-app-env.d.ts
#
In the src/
folder exists a react-app-env.d.ts
declaration file. Declaration files are usually denoted with the .d.ts
file extension and are files that describe the typings of a JavaScript file that exists elsewhere.
/// <reference types="react-scripts" />
A triple-slash directive (///
) is used in the react-app-env.d.ts
file and is a unique TypeScript capability that pertains to single-line comments that contain a single XML tag. Triple-slash directives instruct the TypeScript compiler to include additional files in the compilation process. The directive in the react-app-env.d.ts
file instructs the compiler to include and reference the type declarations of the react-scripts
library which is the library used to build, test, and run our React application.
With that said, there has been discussion among the community as to why this particular declaration file is placed within the src/
folder, and not in a types/
folder of sorts. An open issue currently exists where the React team is currently looking to place a comment in the react-app-env.d.ts
file to better explain the purpose of this declaration file.
Rest of src/
#
The rest of the src/
folder contains a few of the other files responsible in setting up the UI we see when we start our client application.
App.css
: CSS file used in the<App>
component.App.test.tsx
: The test file of the<App>
component that demonstrates the use of the Jest testing framework installed in our application.App.tsx
: The parent<App>
component that contains the boilerplate code shown in our UI.index.css
: CSS file used in thesrc/index.tsx
file.logo.svg
: The React logo in SVG format used in the<App>
component.
We'll remove the index.css
, App.tsx
, App.test.tsx
, App.css
, and the logo.svg
file from the src/
folder. In the src/index.tsx
file, we'll remove the imports of the removed files and in the render()
function, simply render a single <div>
element that says 'Hello World!'
for now.
import React from "react";
import { render } from "react-dom";
import * as serviceWorker from "./serviceWorker";
render(<div>Hello World!</div>, 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();
.gitignore
#
The .gitignore
file dictates the files we don’t want to check in with git
. This includes node_modules/
, the bundled build/
folder when created, and any .env
files.
package-lock.json
#
The package-lock.json
file is an automatically generated JSON file that stores a dependency tree that highlights the dependencies installed from the package.json
file at that moment in time. It should be committed to source code but we'll never make changes to it directly.
package.json
#
This page is a preview of TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL