Let’s create a project folder and package.json file:

$mkdir webpack-demo && cd webpack-demo
$npm init

Babel

For this project we will be using babel and it’s dependencies which help us transform ES6 files to ES5 javascript.

$npm install babel-loader babel-core babel-preset-es2015 babel-preset-react --save-dev

Webpack

We will use webpack along with webpack-dev-server which is a handy server that will create bundle and auto reload whenever we make changes in the code.

$npm install --save-dev webpack webpack-dev-server

Loaders

We will also require CSS and style loader to include our styles in HTML.

$npm install --save-dev style-loader css-loader

Plugins

We will also be using html-webpack-plugin which will generate HTML file for us.

$npm install --save-dev html-webpack-plugin

React

$npm install --save-dev react react-dom

Set up webpack and webpack-dev-server

Add the following lines in the package.json file:

"scripts": {
    "build": "webpack",
    "start": "webpack-dev-server --content-base build"
  }

So the package.json file now looks something like this:

{
  "name": "webpack-demo",
  "version": "1.0.0",
  "description": "Using webpack for react.js applications",
  "main": "index.js",
  "author": "Kushal Dongre",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.4.5",
    "babel-loader": "^6.2.1",
    "babel-preset-es2015": "^6.3.13",
    "babel-preset-react": "^6.3.13",
    "babel-runtime": "^6.3.19",
    "css-loader": "^0.23.1",
    "html-webpack-plugin": "^2.7.1",
    "react": "^0.14.6",
    "react-dom": "^0.14.6",
    "style-loader": "^0.13.0",
    "webpack": "^1.12.12",
    "webpack-dev-server": "^1.14.1"
  },
  "scripts": {
    "build": "webpack",
    "start": "webpack-dev-server --content-base build"
  }
}

Here you can see there are two scripts: build and start.

  • The build script invokes the webpack and builds a bundle just once.
  • start script creates a live reloading server that looks for changes and automatically creates a bundle.

Webpack configuration

We will now create webpack.config.js file which will be in the root directory. This file will contain all the configuration details like input, output, loaders and optionally plugin details.

var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
	entry: {
		app: ['./index.jsx']
	},

	output: {
		path: './dist',
		filename: "bundle.js"
	},

	module: {
		loaders: [
			{
				test: /\.css$/,
				loader: 'style!' + 'css'
			},
			{
				test: /\.(js|jsx)$/,
				exclude: /node_modules/,
				loader: 'babel-loader',
				query: {
					presets: ['react', 'es2015']
				}
			}
		]
	},

	plugins: [
		new HtmlWebpackPlugin({
			title: 'This is a react app which uses webpack'
		})
	]
};
  • The configuration file contains an entry point. In our example it is index.jsx. Lets create the file $touch index.jsx
import './style.css';
import React from 'react';
import ReactDom from 'react-dom';

ReactDom.render(<h1>Hello from react backed by webpack</h1>,
document.body);
  • Next we have specified output file bundle.js which will be under the folder dist
  • Loaders: It contains test which has a regex. In our example it specifies css files. The loader key contains the npm module names chained in reverse order. In our example we want to take css file and load it has style tag. The chaning is done by specifying ‘!’ mark.
  • Plugins: We are using html-webpack-plugin which will create HTML file for us with a title specified in config file.

This config file allows us to build bundle in two ways:

build

$npm run build which runs only once.

Hash: fe111a361b4ba2fb4cd8
Version: webpack 1.12.12
Time: 549ms
     Asset       Size  Chunks             Chunk Names
 bundle.js     1.5 kB       0  [emitted]  app
index.html  186 bytes          [emitted]
   [0] multi app 28 bytes {0} [built]
   [1] ./index.jsx 0 bytes {0} [built]
Child html-webpack-plugin for "index.html":
        + 3 hidden modules

start

$npm run start runs server on port 8080

http://localhost:8080/webpack-dev-server/
webpack result is served from /
content is served from /Users/kushal/workspace/reactjs/demo/webpack-demo/build
Hash: fe111a361b4ba2fb4cd8
Version: webpack 1.12.12
Time: 541ms
     Asset       Size  Chunks             Chunk Names
 bundle.js     1.5 kB       0  [emitted]  app
index.html  186 bytes          [emitted]
chunk    {0} bundle.js (app) 28 bytes [rendered]
    [0] multi app 28 bytes {0} [built]
    [1] ./index.jsx 0 bytes {0} [built]
Child html-webpack-plugin for "index.html":
    chunk    {0} index.html 412 kB [rendered]
        [0] ./~/html-webpack-plugin/lib/loader.js!./~/html-webpack-plugin/default_index.ejs 346 bytes {0} [built]
        [1] ./~/lodash/index.js 411 kB {0} [built]
        [2] (webpack)/buildin/module.js 251 bytes {0} [built]
webpack: bundle is now VALID.

You can now open the location http://localhost:8080/webpack-dev-server/ in browser and see HTML page with our title showing up.

Source code

That’s it!