Wednesday, February 1, 2017

Getting Started with React, Babel and Webpack

React is getting popular everyday and I believe you can find many articles to know what React is. In this post let’s see how we can setup a HelloWorld React application using some set of nice tools.

To build this sample, I am going to use following set of tools and libraries.
This is the editor that I am going to use, and of course, you can use any editor you prefer. But I suggest you try out Visual Studio Code as it offers great features for JavaScript developers. All these features are made possible by the new JavaScript Language Service (Code name : “Salsa”)  which is also getting shipped with Visual Studio 2017.
I am going to use npm as the JavaScript package manager.
Babel is the transpiler here. We can use all the great features in ECMAScript 6, also known as ECMAScript 2015 (ES6/ES2015) and Babel will make sure they will get transpiled to ES5 which will work on all browser versions.
Webpack is the module bundler that I am using, it will be responsible for effectively bundling the files based on the configuration I provide.
I will be using webpack-dev-server to test and host my application. It provides nice features such as hot reloading. We just need to modify the code and changes will get reflected. We don’t need to refresh the browser.

Now it’s time to write some code. I will start by installing the global dependencies that I need. I am going to install webpack-dev-server as a global npm package.
npm install webpack-dev-server -g
Now I am creating a folder for the application “HelloWorldReact” and inside there creating another folder named “app” and that’s where I am going to have all my code files.

From the “HelloWorldReact” folder, I am opening up a command prompt and running the npm init command to create the package.json file. On the prompts, I am just keeping the default values as it is.

Now let’s install the packages using npm.

dependencies
npm install react react-dom --save
devDependencies
npm install webpack babel-core babel-loader file-loader react-hot-loader babel-preset-es2015 babel-preset-react --save-dev
As you already know upon the installation, package.json will get updated. I am further modifying the package.json as follows adding a script.
{
  "name": "helloworldreact",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "start-webpack-server": "webpack-dev-server --hot --inline --colors --progress"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "^15.4.2",
    "react-dom": "^15.4.2"
  },
  "devDependencies": {
    "babel-core": "^6.22.1",
    "babel-loader": "^6.2.10",
    "babel-preset-es2015": "^6.22.0",
    "babel-preset-react": "^6.22.0",
    "file-loader": "^0.9.0",
    "react-hot-loader": "^1.3.1",
    "webpack": "^1.14.0"
  }
}
Here, the packages listed under dependencies are only needed when running the application in production. The packages listed under both dependencies and devDependencies are need when developing the application. Under devDependencies, I have installed,
  • Core Babel package
  • Babel loader for Webpack
  • Two presets to make sure ES6/ES2015 and react transpilation
  • File loader for Webpack
  • Webpack & react-hot-loader to enable webpack dev servers hot loading for React (webpack-dev-server should be running with --hot flag).
The script is for running webpack-dev-server with some set of flags. To know about what these flags are visit webpack-dev-server CLI.

Now let’s create a js file to configure webpack. I am naming it as webpack.config.js.

webpack.config.js
var path = require('path');
var webpack = require('webpack');
 
module.exports = {
  context: path.join(__dirname, 'app'),
  entry: {
    javascript: './app.js',
    html: './index.html'
  },
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  devServer: {
    inline: true,
    port: 9999
  },
  module: {
    loaders: [
      {
        test: /.js?$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        query: {
          presets: ['es2015', 'react']
        }
      },
      {
        test: /\.html$/,
        loader: "file?name=[name].[ext]",
      }
    ]
  }
};
Here I have specified the entry files, bundle output directory, devServer information and loaders. And for js files, I have set the loader as Babel. So what happens in the js loader here is when you come across a path that resolves to a '.js' inside of a require()/import statement, use the babel-loader to transform it before you add it to the bundle. For more information about webpack loaders, go to https://webpack.github.io/docs/loaders.html.

Now let’s create the entry files. Navigate to the “app” folder, and let’s create a app.js and index.html files.

app.js
import React from 'react';
import ReactDOM from 'react-dom';
 
class App extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello World</h1>
      </div>
    )
  }
}
 
ReactDOM.render(<App />, document.getElementById('main'))
index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Hello World</title>
</head>
<body>
  <div id="main">
  </div>
 
  <script src="/bundle.js"></script>
</body>

</html>
Now I am almost good. From the command prompt run the following command.
npm run start-webpack-server 
Now you should be able to see that bundling is happening and webpack dev server is starting. Once completed, navigate to http://localhost:9999 and if all is good you should see something like below.

image
Output
Now try changing the text inside our React component and just save the file, you should be able to see the changes in the browser without refreshing the browser.

Still the bundled files are not outputted to the destination (HelloWorldReact/dist). When you are ready for the deployment, from the command prompt, you can run webpack -d command to output files.

I have made the code available on GitHub. Feel free to fork.
https://github.com/jaliyaudagedara/Blog-Post-Samples/tree/master/HelloWorldReact

Happy Coding.

Regards,
Jaliya