Learn React - Part 1 - Simple setup for a React application with Webpack 4 (+ CSS / SASS)

felipegalvao

Felipe Galvão

Posted on July 26, 2018

Learn React - Part 1 - Simple setup for a React application with Webpack 4 (+ CSS / SASS)

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!

💖 💪 🙅 🚩
felipegalvao
Felipe Galvão

Posted on July 26, 2018

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related