It Isn't Magic, It's Webpack.
Tags: webpack, react, interviewquestions, javascript
Published: 2019-07-07 03:18:58

---
title: It Isn't Magic, It's Webpack.
published: true
description: An in-depth look at Webpack and how it bundles dependencies, particularly in libraries like ReactJS.
tags: Webpack, React, InterviewQuestions, JavaScript
cover_image: https://thepracticaldev.s3.amazonaws.com/i/zpzm1nljlcbpv0ajtmv7.png
---

[Stay hydrated out there](https://amzn.to/3S26cJa)

#Bundlers

Maybe a better title for this post would have been "It Isn't Magic, It's Webpack (or Browserify, Brunch or Parcel, etc.)." These are known as *module bundlers*, which [have been defined](https://github.com/ronami/minipack/blob/master/src/minipack.js) as packages of code that *"compile small pieces of code into something larger and more complex that can run in a web browser."* In essence, this will package all of your stylesheets into one package, your TypeScript into another, all of your JavaScript files into yet another, etc.

Module bundlers essentially figure out which bits of code depend on other bits of code (in other words, bundlers identify dependencies) and make sure code runs in the order it needs to. Bundlers ultimately create a **dependency graph**, starting with a root (which has no dependencies) wherein the further down the graph a bundle of code falls, the more dependencies it has. Further-down code waits its turn for its dependencies to load first before it is loaded itself.

#So, What Is Webpack?

Even in simple applications, we write a lot of code in a lot of separate files. We use syntax like `@import` and ES6. We use helpers like TypeScript to which allow us to write clearer code and catch errors sooner. Think of applications built with component-based libraries and frameworks like [React](https://reactjs.org) where we import components or functions that depend on code written somewhere else in our application. The way our code is parsed, packaged, and executed in a way our browsers can understand can seem like nothing short of magic. But it isn't. **It's a bundler called Webpack.**

What makes Webpack stand out, though, is its ability to gather all dependencies including not just code, but assets such as images, stylesheets (including preprocessors like [sass](https://sass-lang.com/guide), [typescript](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html) and more and create the beforementioned dependency graph. And that's the key -- *the heart of Webpack is building the dependency graph.*

#Building the Dependency Graph

The dependency graph consists of a few key components. Here I'll focus on: Entry, Output, Loaders, and Plugins. One can run `yarn add webpack webpack-dev-server --save-dev` and create a `webpack.config.js` file to your app's root directory to get started. Don't forget to update your `package.json` scripts:

 `"start": "webpack-dev-server",
    "build": "webpack"`

###1. Establish an Entry Point

The first thing Webpack does is establish an entry point. This is going to be the root of the dependency graph. We can do this by creating a variable containing an object which points to the source file. This is typically going to be `index.js`.   You can create the object with a simple string, but for scalability and the possibility of a need for multiple entry points, let's use an object.

![entry point example](https://thepracticaldev.s3.amazonaws.com/i/c6ggk618bslok55kv0s5.png)

Simple enough.

###2. Establish an Output

Once Webpack has finished bundling code and creating the dependency tree, it needs to be told where to put the finished product; This is our Output. Remember, you can name the filename parameter whatever you'd like. Typically this will be named something like `main.js`.

![output example](https://thepracticaldev.s3.amazonaws.com/i/z0w0zrnle4th0225iht3.png)

Interestingly enough, this is the base information the application needs to bundle code. With this, you can spin up your local server with `yarn start` and Webpack will begin doing its thing.

###3. Loaders: Bundling File Types Beyond JavaScript

This is where Webpack starts getting so cool. 

Here's a screen grab of some imports from the `index.js` file of a recent React project of mine called [Squad](https://github.com/crishanks/squad-frontend). 

![imports example](https://thepracticaldev.s3.amazonaws.com/i/ogyxjw9p592j6ivh2kop.png)

It's something we do 100 times a day. But what's really happening behind the scenes? We're telling Webpack about the dependencies `index.js` needs. For example, the line `import ./index.css` tells Webpack to grab those styles. 

In our `webpack.config.js` file, we add a module object like the example below (see [webpack concepts, loaders](https://webpack.js.org/concepts/)).

![loaders module](https://thepracticaldev.s3.amazonaws.com/i/me9hqw5i05ryrb1f8hy0.png)

This object uses a [Regular Expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) to identify certain file types and then tells Webpack which loader to use before bundling. We're saying, "Webpack compiler when you find a path that ends with `.css` in an import, transform/load them using the `css-loader` and `style-loader` when you bundle."

**Important note:** "Transforming" means parsing files (other than `.js` files), and translating it into something else that Webpack and the browser can understand. 

A few examples:
- Have you ever used `@import` or syntax like `url('./icon.png')` in your CSS files? Webpack's [css-loader](https://webpack.js.org/loaders/css-loader/) is the reason why! It parses your `.css` file and processes it. *That is why you can `import Icon from ./icon.png;` and later `element.appendChild(Icon)`!* As stated in the [Webpack Documentation](https://webpack.js.org/guides/asset-management/), "The loader will recognize this is a local file, and replace the `./icon.png` path with the final path to the image in your output directory. The html-loader handles `<img src="./icon.png" />` in the same manner." Isn't that so cool?
- [TypeScript] (https://www.typescriptlang.org/) is a superset of JavaScript that (among other things) allows JS devs to write more statically-typed code to catch errors while writing code. But Webpack doesn't speak TypeScript. The [ts-loader](https://github.com/TypeStrong/ts-loader) parses TypeScript files and converts them into JavaScript Webpack can read. 
- What about any [ES6 syntax](https://www.w3schools.com/js/js_es6.asp) like classes, `let` or `const` variables, arrow functions, default values, destructuring, etc? [babel-loader](https://webpack.js.org/loaders/babel-loader/) parses the code you wrote, identifies ES6 syntax, and loads and transpiles it to ES5 the browser understands.

You can learn more about how loaders work under the hood, and even how to write your own loaders [here](https://webpack.js.org/contribute/writing-a-loader/).

###4. Plugins vs. Loaders

**Loaders**
- Work on a file level
- Help create the bundle (during or before bundle generation)

**Plugins**
- Work on a system level
- Affect the created bundle (bundle or chunk level)
- Focus on optimization ([uglifyJS](https://webpack.js.org/plugins/uglifyjs-webpack-plugin/#root) takes the `bundle.js` and minimizes it to decrease file size)

The code implementation looks something like this:

![plugins example](https://thepracticaldev.s3.amazonaws.com/i/jfur4zom47hn3mzbpvjo.png)

The following [graphic](https://stackoverflow.com/questions/37452402/webpack-loaders-vs-plugins-whats-the-difference) may help visualize the difference as well:

![plugin vs. loader diagram](https://thepracticaldev.s3.amazonaws.com/i/177xjxju6es1511hnwfw.png)

#Summary

Webpack is the culprit behind much of the magical secret sauce that allows us to use syntax and libraries that makes code cleaner, clearer, more scalable. From imports to ES6, developing apps would be difficult without bundlers like Webpack. 

[Stay hydrated out there](https://amzn.to/3S26cJa)

You know what's nice... [A shiny new mechanical keyboard](https://amzn.to/48GVlcT). Click that if you're interested in a good one. Or click this for [another cool option](https://amzn.to/48lQTRe).

Or perhaps you have a good one and you want to [spruce it up a bit](https://amzn.to/3RMztpK) (you know I did).