First things first, why would anyone want to create a react application manually when we have one line installations like:
npx create-react-app <application-name>
Well, as there is nothing wrong with setting up a react application utilizing this method. We can can learn a lot by seeing what goes on under the hood by doing everything manually. Furthermore, we get the added benefit of having more control over the different processes of loading your front-end onto a browser.
Versions Being Used:
- React 18
- Babel 7
- Webpack 5
Pre-Setup
Background Information: In order to get started we need to begin by installing a package manager. A package manager is a tool developers utilize in order to manage the various software packages. This ranges from installation, upgrading, removing, and dependency resolution. One of the most popular options we will look at is NPM
.
1. Node Version Manager (NVM) Installation
We will first be installing a node version manager in order to easily keep track, and manage different versions of node. Since the focus of this article is not about package managers, please follow this article about how to download here.
2. Node Installation
Now that you have NVM
installed, you can run the following script:
nvm install <Node Version>
or install the latest version of Node:
nvm install node
finally, to use the specific node version run:
nvm use <Node Version>
and that is it! You should be good to get officially started.
Setting up the project
1. Initializing package.json
Why use package.json: We use the package.json in order for npm (or yarn) to identify your project and understand how to handle the project's dependencies along with:
- Start your project
- Run scripts
- Install dependencies
- Publish to the NPM registry
Initializing package.json: Now that you know a little more about the importance of having the package.json, run either of the following commands to initialize the file:
npm init
or
npm init -y
the difference between the two is that the -y
will, by default, say yes to every prompted question. The following questions will be presented if you decide to omit the -y
:
package name: (package-name-here)
version: (version)
description: (description of package)
entry point: (file used to start the project)
test command: (script to run test on project)
git repository: (where source code is located)
keywords: (indexed by the NPM registry to find packages when searched)
author: (author of package)
license: (kind of license applied) (typically MIT or ISC)
Learn more about package.json here.
2. Initializing React
Run the following command in the terminal:
npm install --save-dev --save-exact react react-dom
Packages Explained:
-
react
- Will only have the needed functionality in order to define your React components.
-
react-dom
- Serves as the entry point to the DOM and server renders for React.
After the command is run, the following will be created:
- node_modules
- Used to hold all downloaded dependencies from npm.
- package-lock.json
- Used to keep track of exact version of every package installed along with the dependency tree of every package.
*** NOTE: the --save-dev
will save these packages as a dev-dependency. --save-exact
will save the exact package. ***
3. Initializing Babel
Why use babel: Babel is a JavaScript compiler that converts modern JavaScript into code that can be backwards compatible with older versions of web browsers and environments.
Now that you understand the need for babel, run the following command:
npm install --save-dev --save-exact @babel/core @babel/preset-env @babel/preset-react babel-loader
-
@babel/core
- Babel compiler core.
-
@babel/preset-env
- Babel preset for each environment.
-
@babel/preset-react
- Babel preset for all React plugins.
-
babel-loader
- Allows transpiling JavaScript files using Babel and Webpack.
Now, create a configuration file called .babelrc
and paste the following code:
{
"presets": [
"@babel/preset-env",
[
"@babel/preset-react",
{
"runtime": "automatic"
}
]
]
}
These presets is to activate the package when processing this configuration file.
We are also going to be utilizing React's JSX transform from React 17. In order to achieve this we have to set the "runtime" to "automatic". In Babel 8 the default runtime will be set to automatic.
4. Initializing Webpack (and other basic needs)
Now it is time to install webpack and any other necessary packages. Run this line in the terminal:
npm install --save-dev --save-exact webpack webpack-cli webpack-dev-server
-
webpack
- Module bundler with the main purpose to bundle JavaScript files for the browser.
-
webpack-cli
- Command Line Interface (to execute webpack terminal lines).
-
webpack-dev-server
- Utilize webpack with a development server to provide live reloading.
Now, run the following script:
npm install --save-dev --save-exact html-webpack-plugin style-loader css-loader file-loader
-
html-webpack-plugin
- Simplifies creation of HTML files to serve your bundles.
- This plugin is useful when webpack bundles include a hash in the file name. Learn more about the importance of hash here.
-
file-loader
- Resolves import/require() on a file into a url and emits the file into the output directory.
-
css-loader
- Interprets import and url like import/require and will resolve them.
-
style-loader
- Inject CSS into the DOM.
Finally, at the root of the project, create a webpack.config.js file and write the following:
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
module.exports = {
entry: "./src/index.js",
mode: "development",
output: {
filename: "bundle.[fullhash].js",
path: path.resolve(__dirname, "dist")
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html"
})
],
resolve: {
modules: [__dirname, "src", "node_modules"],
extensions: ["*", ".js", ".jsx", ".tsx", ".ts"]
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: ["babel-loader"]
},
{
test: /\.css$/,
exclude: /node_modules/,
use: ["style-loader", "css-loader"]
},
{
test: /\.(png|svg|jpg|gif)$/,
exclude: /node_modules/,
use: ["file-loader"]
}
]
}
}
- Entry:
- Indicates which module webpack should use to begin building out its internal dependency graph. From that entry point, webpack will figure out which other modules and libraries that entry point is dependent on. Learn more about Entry here.
- Output:
- Tells webpack where to emit the bundles it creates and how to name these files. Learn more about Output here.
- Plugins:
- Plugins can be leveraged to perform a wider range of tasks like bundle optimization, asset management and injection of environment. Learn more about Plugins here.
- Resolve:
- Changes how the modules are resolved. Learn more about Resolve here.
- Modules:
- This field can also be called "Loaders" and allows webpack to process other types of files and convert them into valid modules that can be consumed by your application and added to the dependency graph. This is done because webpack only understands JavaScript and JSON files. Learn more about Loaders here.
Time to Program!
1. Create Hello, World!
Create a folder called "src" with the following files:
- App.js
const App = () => (
<div>
<h1>Hello, World!</h1>
</div>
);
export default App;
- index.js
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';
const rootElement = document.querySelector('#root');
if (!rootElement) throw new Error('Failed to find the root element');
const root = createRoot(rootElement);
root.render(
<StrictMode>
<App />
</StrictMode>
);
- index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
2. Run program
Now, in the package.json file, add these lines to your scripts section:
"start": "webpack serve --open",
"build": "webpack --config webpack.config.js --mode production"
Command line explained:
-
npm run start
- Serve will run the
webpack-dev-server
-
--open
will allow webpack to launch browser automatically
- Serve will run the
-
npm run build
-
--config webpack.config.js
provide path to webpack configuration file -
--mode production
defines mode to pass to webpack
-
Now in the terminal just run npm run start
and you will see your application run!
Bonus!
Script Commands: When running the command npm run build
webpack will build the project and create a "dist" folder. This folder will have all of the information that will be sent to the browser for production mode.
Package Management: Every package is currently saved as a dev-dependency. This is done because it is not necessary to send these packages to the client-side since we are going to be transpiling our code to vanilla JavaScript with Babel. The install commands all come with --save-exact
in order to keep control of all package versions.
View everything together in Github.
If you found this helpful or just enjoyed reading the article, consider grabbing me a cup of coffee.
Top comments (1)
Thanks!