Originally published in my blog
Hey folks, how are you doing? In this post, I will show you a quick and simple Webpack 4 setup for a React application.
I'll assume you already have node
, npm
and the usual suspects installed.
First, let's create our project, running the command npm init -y
:
mkdir webpack-4-react
cd webpack-4-react/
npm init -y
The -y flag is just so that you don't have to keep pressing yes to all of that npm questions that it does when initializing your project.
Wepback's installation
Now, let's install Webpack, so that we can use it in our project. I have been using yarn, but npm works just as fine. To summarize, if you are using npm, just change all calls to yarn add x
for npm i x
, and when you need to install as development dependencies, switch yarn add x -D
for npm i x -D
.
Continuing, let's add Webpack as a development dependency in our project:
yarn add webpack webpack-cli webpack-dev-server -D
This will install Webpack development packages, and also Webpack's development server, which we can use to serve and test our application locally. This will also update our package.json
file, adding these packages as development dependencies.
Creating our files
Now, let's create a basic HTML file with a script tag pointing to the main.js
file. This index.html
file will be located in the dist
folder, as will the main.js
file, which will be created by Webpack (so, there's no need to create it manually). This Javascript file will contain our React application code and will be generated by Webpack.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>React and Webpack4</title>
</head>
<body>
<section id="index"></section>
<script type="text/javascript" src="main.js"></script>
</body>
</html>
Now, we should create a src
folder, and inside of it, the index.js
file, which will be the starting point for our React application. It's structure will be the most simple React code.
import React from "react";
import ReactDOM from "react-dom";
const Index = () => {
return <div>Hello React!</div>;
};
ReactDOM.render(<Index />, document.getElementById("index"));
Now, for that to work, we need to add the initialization scripts to our package.json
file. These scripts will make so that Webpack work its magic, transforming our code according to the configuration we'll define in a few minutes. The first script is this one:
"start": "webpack-dev-server --mode development --open",
You will use this script for local development. It will use webpack-dev-server
to serve your files locally and it will generate the main.js
file that we linked in out HTML file some lines above. The --open
flag in the end will make so that Webpack opens your default browser in the local address your application is being served. The other script is this one:
"build": "webpack --mode production"
With this script, Webpack development server will not run, but Webpack will generate your application file ready for production, with all of the code minified and some additional stuff.
Add these two scripts inside of the scripts
key. Your package.json
file should now be like this:
{
"name": "webpack-4-react-boilerplate",
"version": "1.0.0",
"author": "",
"description": "",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server --mode development --open",
"build": "webpack --mode production"
},
"keywords": [],
"license": "ISC",
"devDependencies": {
"webpack": "^4.16.1",
"webpack-cli": "^3.0.8",
"webpack-dev-server": "^3.1.4"
}
}
Webpack configuration
Well, now, if you try to run these comands with yarn run start
or yarn run build
, they will not work. That is because, for Webpack to understand the React code we created, we need some tools to transpile, that is, transform the React code we wrote in code that can be understood by any browser. Let's do this. First, let's install the essential React packages, React
and React DOM
.
yarn add react react-dom
Then, we need to install Babel and some loaders to transpile our code. These ones shall be installed as development dependencies:
yarn add @babel/core babel-loader @babel/preset-env @babel/preset-react -D
After these installations we made, your package.json
file should be looking something like this:
{
"name": "webpack-4-react-boilerplate",
"version": "1.0.0",
"author": "",
"description": "",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server --mode development --open",
"build": "webpack --mode production"
},
"keywords": [],
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.2.2",
"@babel/preset-env": "^7.3.1",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.5"
"css-loader": "^1.0.1",
"node-sass": "^4.10.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"webpack": "^4.26.0",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.10"
},
"dependencies": {
"react": "^16.6.3",
"react-dom": "^16.6.3",
"react-scripts": "2.1.1"
}
}
Now, we need to create a Webpack configuration file, the webpack.config.js
file. In my previous post about Webpack, I already talked about it, so I'll be more brief in this one. Your file should be like that:
module.exports = {
entry: ["./src/index.js"],
output: {
path: __dirname + "/dist",
publicPath: "/",
filename: "main.js"
},
devServer: {
contentBase: "./dist"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
}
};
It's the most simple Webpack configuration file possible. A brief explanation: in entry
, we define the entry file for our application; in output
we include the definitions for the Javascript file that will be generated by Webpack; in devServer
we define the folder from which the development server will serve the files; and in module
we define the general rules for the application, for example, in this case, what will be used to transpile each type of file.
Along with the Webpack configuration file, since we defined babel-loader
to transpile our .js
files, we need to create the Babel configuration file, that will indicate which loaders should be used by Babel to transpile our code. This file, as well as the Webpack configuration one, should live in the root of your project, and should be named .babelrc
. It is also a pretty simple file, that should be like this:
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
Now, we can run our command to start the development server locally:
yarn run start
If everything went right, you will see your browser opening, and in the screen, your React component with the Hello React
message. If you removed the --open
flag from the initialization script, you can access the default address for webpack-dev-server
, which is http://localhost:8080/
Adding CSS
To add CSS, we need to do a little more. To transpile CSS files and use them in our React application, we need some more loaders. Since we're adding CSS, let's make use of SASS to have some additional functionality in our style files. First of all, let's install some packages: css-loader
, style-loader
, sass-loader
and finally, node-sass
. All of them should be installed as development dependencies:
yarn add css-loader style-loader sass-loader node-sass -D
Now let's add another entry in our webpack configuration file. This entry will tell webpack what it should do with .scss
files, which are SASS standard file format. Your webpack.config.js
file will now be like this:
module.exports = {
entry: ["./src/index.js"],
output: {
path: __dirname + "/dist",
publicPath: "/",
filename: "main.js"
},
devServer: {
contentBase: "./dist"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.scss$/,
use: [
{
loader: "style-loader"
},
{
loader: "css-loader"
},
{
loader: "sass-loader"
}
]
}
]
}
};
Now, you should create your main style file. Inside of src
, you can create the styles
folder, to better organize your style files. From your main style file, you will be able to import other specific files. So, let's create the /src/styles/main.scss
file:
p {
background-color: teal;
}
Now, inside of you main React file, all you need to do is import the SCSS file with import "./styles/main.scss";
. Your index.js
will now be like this:
import React from "react";
import ReactDOM from "react-dom";
import "./styles/main.scss";
const Index = () => {
return (
<div>
<p>Hello React!</p>
</div>
);
};
ReactDOM.render(<Index />, document.getElementById("index"));
And now you can see how your Hello React
message have a different background color.
As I mentioned, you can import other style files inside of the main one. One thing that I like to do is to have separate style files for components. So, for example, I can create a components
folder. Inside of that folder, I'll create a _Component.scss
. Let's then, create the /src/styles/components/_Component.scss
file and include some basic CSS in it:
p {
color: white;
}
Now, on the main.scss
file, all you need to do is import it, just like this:
@import "components/Component";
p {
background-color: teal;
}
And now, when your browser refreshes, you will notice that the paragraph with your "Hello React" message now have a white font color. The main requirement for importing in .scss
files like this is that the file to be imported should have its name starting with _
.
And just like this, we have a as simple as possible but pretty complete project with React, Webpack 4 e SASS.
If you want to see the final code, you can access the Github repo clicking here. Feel free to clone it, use it as a boilerplate, whatever.
Hope this React setup is useful. Any questions, just leave it in the comments section.
Cheers!
Top comments (3)
thanks for this tutorial.
maybe it is just me but this only worked for me after i replaced "babel-core": "6.26.3" with "@babel/core": "7.2.2" in the package.json devdependencies
Hey JD! Thanks for your comment.
You are right, the older versions of Babel will not work with the configuration file that I created in this post. For those who install "babel-core" newer versions, there shouldn't be a problem. I have updated the
package.json
file to use the newer versions already.Cheers!
Thank you :)