React without create-react-app Webpack 5
Tags: react, webpack
Published: 2020-12-30 17:16:08

We are going to create a react app with webpack 5.

Here is the code if you just want to copy and paste here is the [webpack config file](https://github.com/rogeliosamuel621/PaymentApp/blob/dev/webpack.config.js) and the [babel config file](https://github.com/rogeliosamuel621/PaymentApp/blob/dev/.babelrc)

If you like to know why these modules, read dawn there.

## Tutorial

We create our folder

```
mkdir webpack5
cd webpack5
npm init -y
```

and we install the following modules

```
npm i react react-dom
```

```
npm i @babel/core @babel/preset-env @babel/preset-react babel-loader clean-webpack-plugin css-loader file-loader html-webpack-plugin mini-css-extract-plugin react-hot-loader webpack webpack-cli webpack-dev-server --save-dev
```

- `@babel/core @babel/preset-env @babel/preset-react` Allows compile modern javascript
- `babel-loader` Allows transpiling JavaScript files
- `clean-webpack-plugin` Allows remove/clean your build folder
- `css-loader mini-css-extract-plugin` Allows use CSS in our projects
- `file-loader` Allows the use of images in our project
- `html-webpack-plugin` Allows creating an index.html in our build folder
- `webpack webpack-cli webpack-dev-server` We are using webpack so we need to use webpack modules xd. webpack-cli let us use webpack commands and webpack-dev-server let us create a server with webpack for mode development
- `react-hot-loader` Allows update react components in real-time

After installing all dependencies we create webpack file and babel file

```
touch webpack.config.js .babelrc
```

Now we create our template, this is our HTML file, which React is going to take to pint him in the DOM

```
mkdir public
cd public
touch index.html
```

And then we create the basic HTML file structure

```html
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>Document</title>
	</head>
	<body>
		<div id="root"></div>
		<!--this is the div that React is going to take-->
	</body>
</html>
```

in webpack file we write this:

```js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { HotModuleReplacementPlugin } = require("webpack");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
	//our index file
	entry: path.resolve(__dirname, "src/index.jsx"),
	//Where we put the production code
	output: {
		path: path.resolve(__dirname, "dist"),
		filename: "bundle.[contenthash].js",
		publicPath: "/",
	},
	// This says to webpack that we are in development mode and write the code in webpack file in different way
	mode: "development",
	module: {
		rules: [
			//Allows use javascript
			{
				test: /\.(js|jsx)$/,
				exclude: /node_modules/, //don't test node_modules folder
				use: {
					loader: "babel-loader",
				},
				resolve: {
					extensions: [".js", ".jsx"],
				},
			},
			//Allows use of CSS
			{
				test: /\.css$/i,
				use: [
					{
						loader: MiniCssExtractPlugin.loader,
					},
					"css-loader",
				],
			},
			//Allows use of images
			{
				test: /\.(png|jpg|svg)$/i,
				loader: "file-loader",
			},
		],
	},
	plugins: [
		//Allows remove/clean the build folder
		new CleanWebpackPlugin(),
		//Allows update react components in real time
		new HotModuleReplacementPlugin(),
		//Allows to create an index.html in our build folder
		new HtmlWebpackPlugin({
			template: path.resolve(__dirname, "public/index.html"), //we put the file that we created in public folder
		}),
		//This get all our css and put in a unique file
		new MiniCssExtractPlugin({
			filename: "styles.[contentHash].css",
		}),
	],
	//Config for webpack-dev-server module
	devServer: {
		historyApiFallback: true,
		contentBase: path.resolve(__dirname, "dist"),
		hot: true,
		port: 8000,
	},
};
```

Now we write this in .babelrc

```
{
  "presets": ["@babel/preset-env", "@babel/preset-react"]
}
```

And finally, we write our commands

```json
"scripts": {
    "dev": "webpack serve --open chrome",
    "build": "webpack --mode production",
    "start": "npm run dev"
},
```

And that's it, we have the configuration.

Now the only thing that we are going to do is check if the configuration that we did works (it works) creating a simple hello world with react so you can stop reading or keep reading.

## It works?

short answer: yes

long answer:

We create the folders and file _(in the root folder)_ that we are going to use

```
mkdir src
cd src
touch index.jsx App.jsx styles.css
cd ..
```

We write the next code

- index.jsx

```jsx
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

ReactDOM.render(<App />, document.getElementById("root"));

module.hot.accept();
```

- App.jsx

```jsx
import React from "react";
import "./Styles.css";

const App = () => {
	return (
		<div>
			<h1>Hello world</h1>
		</div>
	);
};

export default App;
```

- Styles.css

```css
body {
	background-color: black;
}
h1 {
	color: white;
}
```

we run the command

```
npm run dev
```

And we have this application

## Bonus

If you want to add more functionalities to your react apps, here there are some modules that can help you.

- [dotenv-webpack](https://www.npmjs.com/package/dotenv-webpack), to use it you just need to require in webpack file and add it as a plugin.

```js
//some code...
const Dotenv = require('dotenv-webpack');
//some code...

plugins: [
  //plugin...
  new Dotenv(),
  //plugin...
],
```