React Environment: NPM + Webpack + Babel

Building a React component is easy. It’s setting up the environment that’s tricky — you’ll need npm, webpack and Babel to get started. Once set up, webpack will take all your files, compile them into JavaScript the browser can understand, and output them to one single file.

To start a new React project, create a new directory call webpack-test-project and cd into it. Run npm init. This will create a package.json file in the root of your project.

Next run npm install –save react react-dom. This will create a new folder in the root of your project call npm_modules and will download the react and react-dom modules to it, along with any of their dependencies. As well, package.json will be populated with a dependencies object that includes any downloaded modules. This is great because instead of pushing all your modules to GitHub, a teammate can clone your project, run npm install, and presto, react and react-dom will be downloaded to their npm_modules folder.

Next, you need to install webpack via npm. webpack is module bundler. It will take our assets and transpile them according to the specifications in our config file. In this case, we’ll be configuring webpack to use babel and babel-preset-react to compile our code. By compile, I mean that webpack will process our React code to modern javascript that the browser can understand. Babel can also process ES6 & ES7 to JavaScript the browser can understand.

To install webpack and Babel run npm install –save-dev html-webpack-plugin webpack webpack-dev-server babel-{core,loader} babel-preset-react. Notice that this time we used –save-dev because we will only be using these packages in development mode. All of these packages will now be listed in package.json:

Next run mkdir app && cd app and create an index.js and index.html file. Then, in the root of the project create webpack.config.js — we’ll use this file to configure webpack.

We configure webpack by building an exports object, with three important keys: entry, output, and module. Entry tells webpack which files to process; Output tells webpack to bundle your JS files into one new file called index_bundle.js that lives in a new folder /dist in the root of our project. Module tells webpack which loaders (processors) to use to compile our React code into JavaScript the browser can understand.

The Module object contains an array of loaders. In this case we only need one loader, babel-loader, to process our code. In the loaders array we tell webpack to take any file that ends in .js (except those in the node_modules folder) and process them with babel-loader.

But we aren’t finished yet, Babel has its on config file. Create a .babelrc file in the root of your project that tells Babel which presets/processors to run on your code, in this case react.

Ok, almost finished with configuration. The only outstanding issue is instruct webpack to create a new index.html file in the /dist folder and link to the bundled script, index_bundle.js. We will use the HTML webpack plugin to accomplish this task. Run npm install –save-dev html-webpack-plugin. This will update your dependencies in package.json and download the plugin to node_modules. Next, we initialize the plugin in webpack.config.js.

First, declare a new variable and set it to the HTML webpack plugin module. The object we pass to HtmlWebpackPlugin on initialization contains three properties: template, filename and inject. Template points to the file we would like to transform, filename specifies the name of our output, and inject specifies where in the output we want webpack to put the link to the bundled file, in this case the body tag. Then, at the end of the exports object, add a new property plugins and set it to our plugin instance, HtmlWebpackPluginConfig.

Phew, now all the architecture is in place but we still need to define scripts to run webpack. We’ll use two scripts, one for production, webpack -p, and one for development, webpack-dev-server, and put them in package.json. We’ve named our scripts production and start.

Scripts allow us to define shortcuts for common administrative tasks like bundling code. To bundle and compile our code for production as configured in webpack.config.js, run npm run production. After, you should have a new folder in your root project, /dist, with a new index.html file linking to a single compiled file, index_bundle.js, with all of our JavaScripts ready for the browser. You’re file structure should look like this after running the command.


Finally, let’s test this all out with some code. In index.html  create a div element with an id set to app.

And in index.js, fetch the app element and set its inner HTML to “Hello World!”.

Run npm run production one more time. Now when you open ./dist/index.html you should see Hello World! in the top left of your window, which means npm, webpack and Babel are all working properly!

And check out your dist/index.html file. It should be exactly the same except it will link to index_bundle.js in the body.

index_bundle.js will contain a minified version of index.js, transpiled to browser-friendly JS.

Finally, because we aren’t in production mode most of the time, it makes more sense to only compile our code when pushing to production. While in development mode, take advantage of the start script we defined about in package.json. Run npm run start and you can view your progress at http://localhost:8080.

Setting up the environment for React is a bit complicated but it gets easier with practice. I recommend building the environment a few times. In my next post, I will show how to build a React component to display “Hello World!”.

For further information on setting up the React environment, check out this amazing free tutorial which informed much of this post.






Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s