Webpack became the de-facto standard module bundling and build automation tool for React community. Webpack is robust, and more complex than other bundling packages, and it has a steep learning curve comparing to other build automation tools.
This post is going to show how to setup a very basic development environment that will give you a head start for basic web Single page application that is using react and webpack.

Start with NPM packages

Start with installing the essential React required packages:

npm init
npm install --save react react-dom react-addons-update 
npm install --save react-router reflux reflux-promise

The above will start the  package.json  file, and install the required react libraries.


Install webpack and its developer tool

npm install --save webpack
npm install -g webpack-dev-server


webpack configuration file

Start writing the webpack configuration file, which by convention its default name is  webpack.config.js .

var path = require('path');
var webpack = require('webpack');

module.exports = {
   // ..... configuration fields (e.g.: entry, output, .....etc.)
}


entry / output

These most important fields in the config file are the entry/output. Webpack after all is a bundler tool that read JavaScript file and bundle it with all its depnedencies into one or more files (called bundles).
The entry field should point to the main entry point of our application. Webpack will parse the file, and parse all dependencies expressed with the statment  require . The output field is where webpack will store the result.

module.exports = {
    // the most important fields in the configuration
    entry: 'src/app.js',
    output: {
       filename: 'output/main.js'
    }
}


Running the webpack from the command line for the above config file will read the entry javascript file: src/app.js , figure out the dependencies, bundle them all together, and generate the output file output/main.js.


Continous watching and bundling

As other build tools like Gulp provides gulp.watch, and Browserify provides watchify to provide the ability for continous watching changes in source code, and bundle and generate the output on the fly.
Webpack provides the same functionality with running webpack while specifying the watch switch

webpack --watch 
#### or another option
webpack -w

By specifying the watch option , webpack keep watching the changes and recompiles automatically.


Webpack-dev-server

Webpack-dev-server is a solution that was built on top of the watch mode, and goes beyond that. It is a simple node/express server that run our application and serve the webpack bundles. The server watch changes in the source, and emits information about the state to the client.
There are two different ways that the webpack watches the changes in the source files: iframe mode, and inline mode. We are going to cover the inline mode only.
To run the server in inline mode we run the command line as follows:

webpack-dev-server --inline

And the bundle and the static files will be servered at:

http://localhost:8080/

Because we might use this command every time we do development, it is good to put it as a script in package.json.

// in the file package.json
...
"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "start": "webpack-dev-server --colors --inline"
}

On the browser side we need to open socket to the server to allow the server to communicate when change occurs. To do that we have to call this script, which we should add it to the entry point in webpack.config.js.

entry: [
      // WebpackDevServer host and port
      'webpack-dev-server/client?http://localhost:8080', 
      'src/app.js'
]



Hot Module replacement

Hot Module Replacement (HMR) is a feature to inject updated modules into the active runtime.
It help webpack-dev-server loads only the changed bundles, and not the whole code, and the the scripts will be loaded without the need to refresh.
To use the HMR we need to do the following:

  1. Install the hot load package:
  2. npm install --save-dev react-hot-loader
  3. Use hot command line argument
  4. Send a command line option: hot on the CLI of webpack-dev-server, so we can re-write the code to run webpack-dev-server as follows:
    // in the file package.json
    ...
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
      "start": "webpack-dev-server --colors --inline --hot"
    }
    
  5. Load a module on the browser side to watch for the HMR
  6. and we can load it similar to how we loaded the webpack-dev-server client as follows:
    entry: [
          // WebpackDevServer host and port
          'webpack-dev-server/client?http://localhost:8080', 
          'webpack/hot/dev-server',
          'src/app.js'
    ]

Additional useful packages

There are addional useful packages that we are going to usethem in many different projects.

  1. classnames
  2. This package is the official replacement for classSet that was shipped with React.js Addons bundle before. It generates dynamic classnames from the model, similar to Angular's ng-class.
  3. Babel's packages:
  4. Babel provides lots of features like ES6, JSX,
    npm install --save babel babel-core babel-polyfill babel-loader babel-preset-es2015
    


Setup Babel with react

Babel is a modular echo system, and in order Babel provides a module for react, to use it we need to install it and configure it:

npm install --save  babel-preset-react

And to configure it we add a file called  .bablerc 

// .babelrc 
{
  "presets": ["react"]
}



Convert SCSS to CSS

Webpack provides the ability to transfer the content of files through loaders. To transform SCSS to CSS, we do the following:

  1. Install the required loader
  2. npm install sass-loader node-sass webpack --save-dev
    sass-loader is the required loader, and it require node-sass as well to work.
  3. Transform the sass files
  4. To transform the sass files, we use the module/loaders in webpack as follows:
    module.exports = {
      ...
      module: {
        loaders: [
          {
            test: /\.scss$/,
            loaders: ["style", "css", "sass"]
          }
        ]
      }
    };
    

By this you have a basic build system using webpack.