Introduction
Ever wondered how tools like Create React App work under the hood? Setting up a React development environment manually gives you a deeper understanding of the underlying concepts. In this guide, we'll walk through creating a React environment from scratch, covering essential tools like Webpack and Babel. You'll learn how to transpile code, bundle files, and configure a development server, all while gaining valuable insights into how React applications come to life.
What is React
React is a JavaScript library for building user interfaces, primarily for web applications. It enables developers to create reusable UI components that manage their state and render efficiently in response to data changes.
Role Of Development Environment
The development environment will:
Compile
JSX
Transpile JavaScript
Generate
index.html
file, andSave and Reload the application
Steps
Step #1: Download and Install Node.js
Download and install Node.js
which we use to run the development environment.
Step #2: Create and Initialize a Directory
Create a directory, react-app-from-manual-setup
and initialize it
mkdir react-app-from-manual-setup
cd react-app-from-manual-setup
npm init -y
This will create a new empty package.json
file which will list all the dependencies.
Step #3: Install Necessary Dependencies
First, we install react@16.12.0
,and react-dom@16.12.0
by running the following:
npm i react@16.12.0 react-dom@16.12.0
react@16.12.0
and react-dom@16.12.0
are two foundational packages for working with React applications.
react@16.12.0
package provides the core functionality of React. It includes:
Components: The building blocks for creating user interfaces. You can define reusable components with
props
andstate
to manage UI elements.JSX Syntax: A syntax extension for JavaScript that allows you to write HTML-like structures within your code. These structures are then transformed into regular JavaScript function calls.
State Management: React allows components to maintain internal state, which controls how the component behaves and renders.
Lifecycle Methods: Components have lifecycle methods that you can use to perform actions at different stages of their lifecycle (e.g., mounting, updating, unmounting).
react-dom@16.12.0
package serves as the bridge between React and the DOM (Document Object Model) of your web page. It offers functionalities like:
DOM Manipulation: It allows you to update the browser's DOM by rendering React components.
Hydration: This is a process of synchronizing the server-rendered HTML with the in-browser React components, leading to a smoother user experience.
Legacy Browser Support: While React itself doesn't directly handle browser compatibility, react-dom provides utilities for supporting older browsers (though using a polyfill library might still be necessary).
Install html-webpack-plugin
by running:
npm i html-webpack-plugin --save-dev
html-webpack-plugin
plugin simplifies the creation of HTML
files to serve your Webpack bundles. This is especially useful for Webpack bundles that include a hash in the filename which changes every compilation.
Step #4: Create a src/
Directory with index.html
and index.js
Files
Create a src/
Directory with index.html
and index.js
Files:
mkdir src
touch index.html index.js
index.js
file acts as the entry point for our React application while index.html
provides the initial HTML
structure and serves as a container for your React application.
Add the following boilerplate to the index.html
file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Create React Development Environment</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
Remarks:
This file provides the initial
HTML
structure for your web page.It includes elements like
<head>
and<body>
tags, along with meta information and styling.Crucially, it contains a
div
element with a specificID
(usuallyid="app"
). Thisdiv
acts as a placeholder where your React application will be rendered.When your application starts, the
index.js
code renders your React components and injects them into the DOM within thisdiv
element.
Add the following code to the index.js
file:
// index.js
import React from "react";
import { render } from "react-dom";
const Home = () => {
return <p>This is a test paragraph!</p>;
};
render(<Home />, document.getElementById("app"));
Remarks:
This file is the starting point where your React application's execution begins.
It typically imports the main React component of your application and renders it using the render function from
react-dom
.This establishes the initial state of your React application.
Step #5: Configure Webpack
Webpack takes the individual building blocks (JavaScript
files, HTML
, CSS
, images
etc.) and combines them into a single, well-structured building (bundled file) that can be easily understood by a browser. It achieves this by:
Identifying dependencies: It analyzes your code to understand how different files depend on each other (imports and exports).
Bundling: It takes all these files and combines them into a single output file (often named
bundle.js
). This simplifies browser loading and reduces the number of HTTP requests needed.Loaders: Webpack can't understand everything on its own. It uses loaders like Babel to transform specific file types (like
JSX
) before bundling them.
Install webpack dependencies by:
# you can install specific versions if needed
npm install save-dev webpack webpack-cli webpack-dev-server
Create a file named webpack.config.js
at the root of your project. This file will contain the Webpack configuration. Add the following:
import path from "path";
import HtmlWebpackPlugin from "html-webpack-plugin";
import { fileURLToPath } from "url";
import { dirname } from "path";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
export default {
entry: "./src/index.js",
output: {
path: path.join(__dirname, "/dist"),
filename: "bundle.js",
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html",
}),
],
devServer: {
static: {
directory: path.join(__dirname, "dist"),
},
compress: true,
port: 9000,
},
};
The code in this configuration file:
sets up a Webpack configuration for a React application.
It handles JavaScript and JSX files, generates an HTML file, and starts a development server.
The
path
module is used to construct file and directory paths.The
HtmlWebpackPlugin
creates theHTML
file that renders the React app.The
devServer
section configures the local development server.
Here is an in-depth summary of what the code does:
Necessary Imports:
import path from "path";
: ImportsNode.js
path module to work with file paths.import HtmlWebpackPlugin from "html-webpack-plugin";
: Imports theHtmlWebpackPlugin
, a plugin that simplifies the creation ofHTML
files to serve your webpackimport { fileURLToPath } from "url";
: ImportsfileURLToPath
method from theurl
module, which converts a fileURL
to a path.import { dirname } from "path";
: Importsdirname
method from the path module, which gets the directory name of a path.
Determining File Paths:
__filename
: Gets the absolute file path of the current module.__dirname
: Gets the directory path of the current module.
Webpack Configuration:
entry
: Specifies the starting point of your application (./src/index.js
).output
: Defines where the bundled file should be output (path
) and its name (filename: "bundle.js"
).module.rules
: Tells Webpack how to handle different file types.Rule for
.js
and.jsx
files:- Uses
babel-loader
to transpile them.
- Uses
plugins
: Specifiesplugins
to be used during the build processHtmlWebpackPlugin
: Creates anHTML
file that references the bundled JavaScript (template: "./src/index.html"
).devServer
: Configures the development serverServes static files from the
dist
directory.Compresses responses for faster loading
Runs on port 9000.
Step #6: Configure Babel
We can think of Babel as a translator. Webpack might not understand the latest JavaScript features (JSX
, classes etc.) you might be using in your React code. Babel acts as a translator, converting your modern JavaScript
code into a version that older browsers can understand (usually ES5
). This ensures wider compatibility for your application.
Install Babel packages needed to transform JS
to JSX
via the following command:
# save to devDependencies
npm install --save-dev @babel/core@7.7.7 @babel/node@7.7.7 babel-loader@8.0.6 @babel/preset-env @babel/preset-react
Create a file named .babelrc
or babel.config.json
at the root of your project. This file will contain the Babel configuration. Then add the following:
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
Remarks:
This is how Webpack and Babel work together:
In the setup, Webpack uses the
babel-loader
to identify and process yourJSX
files.The
babel-loader
then uses Babel's presets (@babel/preset-env
and@babel/preset-react
) to convert your code to a compatible format.Finally, Webpack bundles the transformed code with your other files into a single bundle.
Step #7: Update package.json
Scripts
In your package.json
, add a start script to run your application using Webpack Dev Server
"scripts": {
"start": "webpack serve --mode development",
"build": "webpack --mode production"
}
Our package.json
file should look like this:
{
"name": "react-app-from-manual-setup",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack serve --mode development",
"build": "webpack --mode production"
},
"type": "module",
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"react": "^16.12.0",
"react-dom": "^16.12.0",
"save-dev": "^0.0.1-security",
"webpack": "^5.91.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.0.4"
},
"devDependencies": {
"@babel/core": "^7.7.7",
"@babel/node": "^7.7.7",
"@babel/preset-env": "^7.24.3",
"@babel/preset-react": "^7.24.1",
"babel-loader": "^8.0.6",
"html-webpack-plugin": "^5.6.0"
}
}
Step #8: Run the Application
Start the application by running:
npm start
Open your web browser and navigate to http://localhost:9000. You should see your React application running.
Conclusions and Next Steps
Manual Setup vs. Toolchains:
While this manual approach offers a valuable learning experience, it can be time-consuming. Setting up Webpack, Babel, and managing configurations can take away from development time. React toolchains like Create React App, Vite, and Next.js come pre-configured with all the necessary tools and functionalities. This eliminates the need for manual configuration, allowing you to focus on writing code and building your React application faster.
Boosting Productivity:
These toolchains offer additional features that further streamline development. Create React App provides a hot reloading server for instant feedback, while Vite boasts lightning-fast development server speeds. Next.js goes even further, offering features like server-side rendering and automatic code-splitting for optimized performance. By leveraging these tools, you can significantly increase your development speed and efficiency.