DEV Community

Oliver Mensah
Oliver Mensah

Posted on • Updated on

Using Webpack and React to Achieve Similar Workflow as Create-React-App(CRA) CLI.

Using Create-React-App(CRA) for React project simplifies the development workflow. Behind it, is the usage of webpack for almost all of its tasks. But if you have ever wondered how this CRA works, then this article is for you. This article is about creating React project from scratch with the aid of Webpack.

To get started, we need some packages to help us in creating a React project.

dependencies.

  • react : holds the react source for components, state, props and all the code that is react.
  • react-dom : helps to use React in the browser.

development dependencies

  • webpack
  • webpack-cli
  • webpack-dev-server
  • babel-core
  • babel-loader
  • babel-preset-env
  • babel-preset-react
  • html-webpack-plugin

Having known the packages that we will need for the React Project, let's start by creating a project. Create an empty folder and through your command-line or terminal navigate to the project folder.
Since we will be installing these packages into our project, we need to start by create package.json file that will hold the metadata about our project. You can do this by running

   npm init -y
Enter fullscreen mode Exit fullscreen mode

You then need to install the dependencies as

    npm i react react-dom -E
Enter fullscreen mode Exit fullscreen mode

Once the installation is done, we can now add the devdependencies as

    npm i webpack webpack-cli webpack-dev-server babel-core babel-loader babel-preset-env babel-preset-react html-webpack-plugin -DE
Enter fullscreen mode Exit fullscreen mode

We need to setup configuration for both webpack and babel that will help webpack to know where it should start compiling the necessary files as well as other important information needed for its operation.

At the root directory of your project, create webpack.config.js file and add the following content.

    const path = require('path');
    const HtmlWebpackPlugin = require('html-webpack-plugin');

    module.exports = {
        entry:'./src/index.js',
        output: {
            path: path.join(__dirname, '/dist'),
            filename: 'bundle.js'
        },
        module:{
            rules:[
                {
                    test:/\.js$/,
                    exclude: /node_modules/,
                    use: {
                        loader: 'babel-loader'
                    }
                }
            ]
        },
        plugins: [
            new HtmlWebpackPlugin({
                template: './src/index.html'
            })
        ]
    }
Enter fullscreen mode Exit fullscreen mode

From the config file, we have entry,output, modules, and plugins keys. Webpack simply needs to have these 4 core things to execute properly.

entry: where webpack should start compiling the files from, which is react our entry point, src/index.js
output: where we want our compiled code to go, it is going to be one bundled js file
module: this is where we put all our loaders. Which looks for all js file to be compiled by webpack. Also we don't need the node_modules to be compiled so we exclude them.
plugins: we don't want to manually add the index.html in our dist folder created by building our react project. So we allow the HtmlWebpackPlugin to do that for us. Which basically says create an index.html file in the dist folder using the ./src/index.html file.

We will need to add a configuration for babel on which preset it should use. Create .babelrc file in the project root and add the following content.

    {
        "presets": ["env", "react"]
    }
Enter fullscreen mode Exit fullscreen mode

Awesome, we have a good setup for our development, now we can start writing some react code. But from the webpack configuration, we need to have an entry file called index.js in the src folder so we need to create that. In that file add the following code.

    import React from 'react';
    import ReactDOM from 'react-dom';
    import App from './components/App';

    ReactDOM.render(<App />, document.getElementById('app'));

Enter fullscreen mode Exit fullscreen mode

From the same webpack configuration, we need to create ./src/index.html file. Add these content to it.


    <!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>My React App</title>
    </head>

    <body>
      <div id="app"></div>
    </body>

    </html>
Enter fullscreen mode Exit fullscreen mode

From the ./src/index.js file, we are importing an App component from /components/App to be rendered by the ReactDOM. We need to create that file too.

    import React, { Component } from 'react';
    class App extends Component {
      render() {
        return (
          <div>
            <h1> React is Awesome</h1>
          </div>
        );
      }
    }
    export default App;
Enter fullscreen mode Exit fullscreen mode

To run the sample react app, we need to add to the script in package.json the following scripts.

     "start": "webpack-dev-server --mode development --open --hot",
     "build": "webpack --mode production"
Enter fullscreen mode Exit fullscreen mode

Run the application by executing npm run start in your terminal and also build the react application with npm run build to build the app into the dist folder.

If you have been following along, you can download the code from my github repo

Conclusion.

Now, you have learned how to use webpack with React to achieve almost the same workflow as the CRA CLI and has cleared the doubts on how CRA works.

NB: In case something is not clear enough,let's discuss that in the comment section

Top comments (2)

Collapse
 
evanmcd profile image
Evan McDaniel

Hey Oliver. Thanks for this tutorial. It was super helpful.

Just wanted to note that I ran into a bit of an issue now that Babel 7 is out. I needed to use the updated versions - @babel/core, @babel/preset-env, and @babel/preset-react (babel-loader stays the same for some reason).

So that means installing the above versions instead of what's listed in step 3, and replacing the presets confirm in .babelrc with "presets": ["@babel/preset-env", "@babel/preset-react"]

Everything else worked for me.

Thanks again.

Collapse
 
brownfish profile image
brownfish

Great Article,very helpful fir us beginners.