Webpack: How to Write Code for your ES6 React with Webpack Project

dist/index.html

We can go now open our dist/index.html . This will be the one HTML page that loads our entire app. We don’t need much code at all for this file, just enough to:

  • Set an element for the React DOM in the src/js/client.js .
  • Link to our bundled JavaScript file (which doesn’t exist yet).

Therefore, this is what our dist/index.html file will look like:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>React Webpack Example</title>
</head>
<body>
  <!-- React app will be injected into the following `div` element: -->
  <div id="app"></div>
  <!-- Include bundled JavaScript: -->
  <script src="bundle.js"></script>
</body>
</html>

You might be wondering why this page links to a bundle.js when all we have so far is an empty src/js/client.js . This will be revealed later when we write our Webpack configuration file.

src/js/client.js

Now it’s time to write some React code. Just like in the dist/index.html file, for now we will write just enough code to get the app going, so there won’t be much code required at all:

import React from 'react';
import ReactDOM from 'react-dom';

class Main extends React.Component {
  render() {
    return (
      <div>
        <h1>This is one cool app!</h1>
      </div>
    );
  }
}

const app = document.getElementById('app');
ReactDOM.render(<Main />, app);

The code that looks like HTML elements is actually JSX, which is a part of React.

To explain what is going on in this file, we’ll break it down:

  • First, we are importing React and ReactDOM . These are required for any React file that is used to inject code into the DOM. The ReactDOM is a virtual DOM, and it’s not the same thing as the standard Document Object Model.
  • Help: More about the React DOM
    • Next, we are creating a React class. Classes were added to JavaScript in ES6. Therefore, this is the ES6 method of writing a React class, but of course we can write one in ES5 too.
  • Help: More about ES6 classes

Every React class has a render method. In this case, the render method is return ing a JSX div element. This is what we’ll see all over any React file. The class can contain other methods which must appear before the render method, which always goes at the bottom of a class.

  • Lastly, we are linking React with our index.html . We set the app to be the location of wherever we want our React code to be injected. And finally, using ReactDOM, we inject the component we wrote, <Main /> , into the app, which in this case is the div with the id of app .

webpack.config.js

There’s still one more file left to write before our project is ready. It’s the Webpack configuration file. At first, webpack.config.js files can be confusing to look at, but often, they’re not as complex as they seem.

In this case, at its most basic, a webpack.config.js exports an object that has the following properties:

Property Role
entry What goes in: the entry point of the app. In this case, it’s src/js/client.js .
output What comes out: what Webpack is going to bundle for us. In this case, it’s whatever we name it in the webpack.config.js .
loaders The tasks that Webpack is going to carry out.

Here is what the webpack.config.js file looks like:

var path = require('path');
var srcPath = path.join(__dirname, 'src');
var buildPath = path.join(__dirname, 'dist');

module.exports = {
  context: srcPath,
  entry: path.join(srcPath, 'js', 'client.js'),
  output: {
      path: buildPath,
      filename: "bundle.js"
  },
  module: {
      loaders: <a href='https://en.wikipedia.org/wiki/Don%27t_repeat_yourself' target='_blank' rel='nofollow'>
          {
            test: /\.jsx?$/,
            exclude: /(node_modules|bower_components)/,
            loader: 'babel',
            query: {
              presets: ['react', 'es2015']
            }
          }
      ]
  }
};

Again, let’s break it down so that it’s clear what this file is doing:

  • Firstly, we are requiring NodeJS’s path module so that we can handle file paths, which is required for setting the object’s context . It’s very important to use this module rather than try and concatenate directories with strings, because some operating systems, like Windows, require this.
  • Then, we specify a srcPath and a buildPath using the path module that we just required. Doing this will ensure we have [DRY, readable code.
  • Now comes the time to write the object. The properties we are going to use are all relevant to Webpack.
    • We first provide a context, which simply specifies where our app is. It refers to the context variable that we just created.
    • We then specify the entry point, which is of course the React app we wrote earlier ( src/js/client.js ).
    • Next we specify the name of the bundled file that Webpack creates when it runs. In this case it’s dist/bundle.js . Sound familiar? It should do, because this is the file we are linking to from our dist/index.html !
    • Finally comes the module property, which contains an array, loaders , which currently contains a single object. This object’s properties tell Webpack what JavaScript files are being written with ES6 and React, so that its loader, babel can run accordingly when webpack.config.js is run. This is largely boilerplate code that we can see at the readme page on Babel Loader.

If webpack.config.js is confusing now, don’t worry, as long as you understand what it is there to do.

1 Like