What's a Webpack bundle, and why should you care?
Webpack is billed as a JavaScript module bundler, but what exactly is a bundle? Simply put, a bundle is a generated JavaScript file. So why is this even necessary?
First off, the complexity of a modern Single Page Application using React, Vue, or the like means you need to break your application into modules. You're probably used to working with ES6 modules in the front end (import
and export
) or CommonJS modules in Node (module.exports
). Until recently, there was no option for breaking your code into true, encapsulated modules natively in a browser environment.
Even now, with browser support for modules, you would have to load all of your individual module files in the browser. That brings a great deal of network overhead, both in time and bandwidth.
Out of the box, Webpack walks the dependency graph of your application (see yesterday's email for more on this), removes all of the unused code (called "tree shaking"), encapsulates the scope of each module using closure (not to be confused with the programming language, Clojure), and bundles it all together into a single script that can be delivered to the browser in one HTTP request, containing only the code necessary for execution of the app.
That's already pretty cool. We're allowing the developer to make use of the full expressive range of a module system, but producing the smallest possible script file to be delivered over the network.
But we can go further.
Imagine you have two different pages, each of which loads its own SPA, but which each have many dependencies in common. If we simply compiled a separate bundle for each page, page1.js
and page2.js
, then each bundle would contain a lot of duplicate code. When a user navigates from one page to the next, they'll be needlessly downloading all that duplicate JavaScript. But if we configure Webpack with multiple entry points and code splitting (also known as chunk splitting), it will figure out for you which dependencies are common to your entrypoints and pull them out into their own chunk. So you end up with three JavaScript files: page1.js
, page2.js
, and common.js
. On page one, you would load common.js
and page1.js
, and on page 2 you would load common.js
and page2.js
.
But wait, didn't we just duplicate the code again? If we're including common.js
on both pages, how does that help us?
That's a great question! I'm so glad you asked it! The reason is that browsers are very smart about caching content. When a user navigates from Page 1 to Page 2, the browser will not re-fetch common.js
, but instead load its cached copy. Therefore, it only needs to download page2.js
. Neat!
And this is just the tip of the iceberg. There are many more optimizations to both your dev process and your page performance that can be achieved through Webpack.
More tomorrow.
Next Up:
What's a Webpack Loader, Really?
Previously:
Webpack From Zero