The github repo, react-webpack, has the minimal scaffolding for a React web app with Webpack 2. The tutorial explains how the project was built.

Minimal project

Create the package.json using npm init command.

Install React: yarn add react react-dom

Install Webpack as dev dependencies: yarn add webpack webpack-dev-server --dev

Create Webpack configuration file:

The input for the project is app.jsx file created in a src folder. The output of the project is bundle.js created in a dist folder. Next, we will create React components and process it using babel.

Processing React components

Create two folders, src and dist. The src folder contains all files that will be processed by the build. And dist folder contains the output of the build process. In src folder, we create the app.jsx file, the entry point to the build process.

Home component is rendered within the DOM element using react-dom/ReactDOM. It is a simple component that renders a heading.

Babel builds React components in JSX files. We will install babel and related packages to dev dependencies:

In the build configuration file, use the babel-loader to process JSX files.

The es2015 preset is used to transpile ES 2015 code to ES 5 or JavaScript 5. The react preset is used to transpile JSX code to JavaScript. While importing a JSX file, we exclude the jsx extension: import Home from './components/home';. This is possible with the use of resolve configuration.

We have setup the configuration to process JSX files. Next, we create the HTML file which has the JavaScript bundle.

Serving HTML using the dev server

The index.html file has the script tag for the bundle generated in the build process.

The copy-webpack-plugin package copies the index.html from the src folder to the dist folder.

Install the plugin using yarn add copy-webpack-plugin --dev

Use the plugin to copy the index.html file.

Webpack comes with a dev server. Modify the start script as follows.

Specify a configuration for dev server. The contentBase settings tells the server the folder which serves the content.

Now, we are all set to run our web app.

The web app is available at http://localhost:8080.

Adding a background image

We will continue our exploration of Webpack. Wrap the heading with a container element.

We will add SASS stylesheet home.scss in the folder src/styles/.

The container has the background image. The background image is available in the images folder placed along the src folder.

To process images in the build, we need another loader, file-loader.

The file-loader emits the image file in the output folder. By default, it will emit the file in the output folder as [hash].[ext] to maintain uniqueness. We can override the behaviour by providing a name option. With the option specified above, the file will be emitted in the output folder as images/filename.png.

There is one detail that needs more explanation. How is the SASS file processed? We need more loaders.

To process SASS files, we chain the loaders.

The sass-loader compiles SASS to CSS. Next, css-loader translates CSS into modules. This ensures that import / require statements work. And url() gets resolved. Finally, style-loader injects the styles into the head tag of the HTML file.

The background image file is emitted in the output folder.

Next, we will explore how hot reloading works.

Hot reloading

By default, Webpack does live reloading. When the contents of the app changes, the page reloads. For a good development experience, the page should not reload. Rather, only the affected components should be updated. Hot reloading does that. There is a lot of theory behind how hot reloading works. In this tutorial, we will configure our web app so that both styles and javascript are “hot reloaded” without a browser refresh.

Add the HotModuleReplacementPlugin.

Update the webpack input or entry.

Add the hot flag to devServer configuration.

Webpack is configured with hot reloading. By default, the style-loader has HMR (hot module replacement) enabled. So, all your style changes will be reflected in the page instantaneously. Next, we enable HMR for React components.

Install react-hot-loader package.

Add react-hot-loader/patch to the entry.

Add the react-hot-loader/babel plugin. And update the es2015 preset configuration.

Place our main component within AppContainer component of react-hot-loader.

Finally, we handle the hot update accept handler.

I know. The above steps are a lot of configuration. But at the end of it, we are set for a smooth development experience. We see all our changes reflected in the web page without a browser refresh. Hot reloading saves a lot of time and improves productivity.

ESLint

Linting code makes it consistent and easy for the team to work together. We will add ESLint with eslint-react-plugin.

Add .eslintrc file with the following JSON.

The configuration loads the react plugin and lints code according to recommended rules specified in the plugin.

You will notice a few lint errors related to import and const keyword. We need to provide parsing hints to .eslintrc file as follows.

This will remove some of the lint errors. There are a few more lint errors related to the usage of global variables. We have to create exceptions for those variables.

It will be nice to see the lint errors in the build process. For that, we need eslint-loader.

A new rule in the build process will output all lint errors in the console.

For a more visual output, we can tweak the devServer settings.

If we add an unused variable in our home component, the browser will show the error.

The final dev setting that we will add is SourceMap.

SourceMap

SourceMap is useful for debugging. It shows the original source code in developer tools. We can put breakpoints and walk through the code. SourceMap is generated using the devtool configuration.

There are several options for devtool configuration which is documented here. For most scenarios, the cheap-module-eval-source-map works well.

To view the source map, go to Developer Tools, Sources Tab, and type Cmd-P (on a Mac). A list of source files show up in a dropdown. Select home.jsx to view the source.

 

Production configuration

For generating the production build, create a new configuration file, webpack.production.config.js. We do not need the following sections from the development build.

  1. Hot reloading
  2. Linting
  3. SourceMap
  4. DevServer

For production, we won’t use webpack-dev-server. Instead, we will have a simple Express server, which returns the index.html generated as part of the production build.

  1. Generate the production bundle.
  2. Run the express server.

Add a build script in package.json.

Generate the production bundle.

Minify the bundle using UglifyJsPlugin.

Extract CSS

With style-loader, CSS is injected into a style tag in the head section of the HTML document. Ideally, the CSS should be in a separate file. The extract-text-webpack-plugin helps to extract CSS into a separate file.

Remove the style-loader and replace it with the new plugin.

Add a plugin entry which specifies the name of the CSS file.

Remember to require the plugin at the top.

When the build script is run, a new file, styles.css is generated.

Add a link element to index.html.

Double click the html file and you should see the web page below.

We have come a long way in scaffolding the react application with Webpack. The react-webpack repo has the entire source code. Use this as a starting point for building your React app. I have intentionally avoided adding tests, redux or mobx, express server to keep the source code to the bare minimum possible. I hope you enjoyed it.

Scaffolding React web app with Webpack 2
Tagged on:             

Leave a Reply

Your email address will not be published. Required fields are marked *