Next lesson playing in 5 seconds

  • Overview
  • Transcript

2.2 Webpack

Webpack has become the most commonly used build tool for React projects. In this lesson, we’ll explore the building blocks of Webpack and create a configuration for our project.

Related Links

2.2 Webpack

In this lesson we'll learn about Webpack, a very popular build tool in the React community. If you're used to tools like Grunt or Gulp, you can think of Webpack as being something similar. Now, Grunt and Gulp are general purpose task runners, so they can technically do all Webpack can do, but it requires configuring a bunch of plugins. The Webpack, on the other hand, is a complete module bundler. So what's a module bundler? If you look at any React project, or for that matter any web project, it contains a bunch of static assets, like JavaScript, css, sass files, images, fonts, and so on. Each of these in the Webpack parlance is called a module. Now these modules can depend on eachother, as can be seen by the arrows from one module to the other. Now Webpack, being a module bundler, combines all of these modules into a highly optimized bundle which can then be deployed onto the web. Webpack also takes care of automatically bundling these modules anytime they change, which gives you a nice development time workflow. Now, if you probe a little deeper into Webpack, you will see three fundamental concepts. A Loader, a Plugin, and a Chunk. A Loader is responsible for loading a single file and also optionally transforming it. As an example, you have the sass Loader which loads the sass files and transforms it to css. A Plugin can extend the behavior of the pack and also operate on multiple files at once. As an example, we have the HTML Webpack Plugin which can create the index HTML based on all the bundles you have in your project. And finally the Chunk is the output of Webpack. There could be more than one chunk created depending on how you structure your project. Loaders and Plugins can both contribute in creating the Chunk, also known as the bundle. All right, so with that bit of background on Webpack, let's start building the configuration for our React project. So here, I'll set up a simple React project with two files. The app.jsx simply requires the sass file and also prints out the title for the project. One thing interesting to note over here is that, because of Webpack, you can include and depend on sass files inside a JavaScript file. So this is different from Grunt or Gulp and other projects, where you only depend on JavaScript from other JavaScript files. Whereas here, every module that you need to depend on can be included as a require statement right inside the file. So, those are the react files, now let's focus on the packages and we'll start on the node modules. Now as you've seen before, Webpack relies on a bunch of Loaders to actually load the files and transform them, as well as Plugins to extend the behavior. In our case, we'll use a few Loaders to load a certain set of files, and also one Plugin to create our index html. Let's quickly go through the node modules that correspond to them. Babel-core, babel-loader, and babel-runtime are used to transpile our ES6 or ES2015 files to ES5 JavaScript. The css, sass, and style loaders are used to convert our sass files into css and eventually load them as style tags in our HTML. The url-loader is for loading the font files. And the json-loader is, of course, for loading json, which we'll be using later in our project. We have one plugin, the HTML Webpack plugin, that automatically creates the script tags and the index HTML for all the bundles in our project. And finally, webpack itself is a node module. We also include the webpack-dev-server which is used for development time, it automatically library loads the browser based on changes and auto-creates the bundle. This is extremely useful and definitely a must have for any React project. All right, with that, let's jump in and create our webpack config file. We'll create this file at the root of our project and name it webpack.config.js. Now, every webpack config consists of few key elements: the input, the output, the loaders, and some optional plugins. The configuration itself is an object literal that is exported from our file. The input is best fired with the entry property and in our case it's the app.jsx file. The app property on the entry is the name of the bundle that will be created. The output is specified again as an object literal and consists of the path and the file name. The file name itself references the bundle name in entry with the bracketed name property. Next comes the set of loaders, which will be used to load specific types of files, and also transform them in the process. Every loader is specified by two properties, the test and the loader. The test is specified as a regular expression that is used to identify the file type. Normally by the file extension. The loader is specified by the NPM module name that'll handle the file. It can also be a chain of loaders that'll be handling the file one after the other, as you'll see in case of the sass file. The loader can also take in arguments or options as a query string, which is prefixed by the question mark. In the case of the css loader, you want to take the css outward from the file, and inject it as a style tag. This is why we chain it to the style loader, which will take care of that. Chaining itself is done by demarcating with the exclamation mark. Now the sequence in which the file will be processed should be read right to left. So in this case it will be first handled by the css loader and then sent to the style loader. In case of sass files, it'll first be handled by the sass loader and then sent to css and the style loaders, as can be seen in the configuration over here. Next we have the js and jsx files which are handled by babel and converted to ES file. Note that we're excluding the node modules folder as we want to avoid the files under that. Next I'll add the json and url loaders for handling the json and phone files. The configuration, as you can tell, is very similar to the previous ones. So those are all of our loaders. Now let's jump onto the plugins section. Now as you know, we only have one plugin over here, which is the HTML Webpack plugin. Now that's an node module, so we'll first require that and then create an instance of that in the plugins array. We'll throw out some simple properties to configure this plugin. In this case, just a title to say that it's a React Deep Dive project. Now Webpack can also create source maps for our JavaScript and jsx files, so I'm gonna specify that with the devtool property. And with that, we have our configuration ready. Now, if we switch back to our package.json file, we added two little scripts over there. Build script simply invokes Weback and creates a one time build or a one time bundle. But as dev invokes a Webpack dev-server that creates a reliable loading server that looks for changes and automatically creates the bundle. Now we'll be running the script throughout the development of our project. All right, so at this point, we have our configuration ready, and we also have listed all the NPM modules that we need for our project. This includes the loaders, the plugins, and other dependencies like Webpack and React. So let's go ahead and install it with npm install. So this will make a trip to and fetch all the modules that we need for our project. This should take a short while to download all of them into the node modules folder. Now we have all the ingredients to run our project. So let's do npm run now and launch our Webpack dev-server which will create the initial bundle and wait for changes. Now, by default, the Webpack dev-server launches on localhost 8080. So let's go our web browser and look at that URL. As expected, we see the index.html with the main heading, React Deep Dive. If you open up the Chrome inspector and go to the elements tab, we can also see the title in the head tag and also the link to the styles sheet which combines all the styles in our project. If you go to the sources tab, we can also see our app.bundel.js. Now this contains a lot more than just your project source code since babel also injects some runtime into our final bundle. So don't be alarmed if you find this file a little larger than you expected. Now during development, you don't wanna obviously look at this giant file. Instead we can rely on source maps and quickly jump to the actual file. So here you can see I opened up app.jsx, and you can even set a breakpoint over here, and when you refresh, the break point actually hits inside as well. So this is very convenient, and we don't really have to look at the bundled file. Now the Webpack dev-server actually supports live reloading, so let's test that. Let's go back to our sass file, and make a quick change to the body background. Let's change it to something darker, and save the file, and you can see that Webpack detects the change, and recreates the sass file and reloads the browser. So this is very convenient during development. You can also see this on the command line, where Webpack outputs some computed logs to show you the change as a last recreation of the window. All right, so let's wrap our lesson over here. You have seen the fundamentals of Webpack. We created our webpack.config.js, launched our dev-server, and also showed the live reload of changes. With Webpack in place, we have our base set up to start building our project. In the next lesson, we'll take a speed tour of the ES 6 RES 2015 Syntax, just the essential syntax we would need for our project. I'll see you there.

Back to the top