Webpack
Webpack is a “bundler”. It's the main tool we run to produce a production build of our application.
It's rare these days for developers to configure Webpack directly. Typically, we'll use a tool like Parcel or Next.js to manage it for us. But it's worth understanding how the puzzle fits together.
For example, you might be wondering: if we use Babel to transform our JSX into browser-friendly JavaScript, why do we need Webpack? Where are the boundaries between these two tools?
In this lesson, we'll answer these questions, and build a mental model for how builds actually work.
Transpiling vs. Bundling
Video Summary
- Transpilers like Babel are meant to process files in a 1:1 manner. If I were to point Babel at the codebase for this course platform, it would convert 800 JSX/TS files into 800 browser-friendly JavaScript files.
- This is an untenable number of files. It would take forever to download each individual JS file, especially because it happens in a cascading waterfall.
- Bundlers like Browserify or Webpack exist to solve this problem. They follow all of the import/export statements and package them up into a much smaller number of JavaScript files.
- Webpack is the conductor of the orchestra. It uses the tools we've seen, like Babel and Prettier, to process the files as it bundles.
- Webpack does lots of other smart stuff under-the-hood, like distinguishing between "common" code needed in multiple bundles vs. "single-use" files needed only in a single bundle.
- It might seem as though modern JavaScript tooling is wildly overengineered / overcomplicated, but I actually don't think that's true. The problem is ridiculously complex, which limits how simple the solution can be.
Importing assets
So, here's a peculiar thing you might see in some React codebases:
import catSrc from '../../assets/cat.jpg';
function CatAvatar() { return ( <img alt="Cute cat sitting in a chair like a person" src={catSrc} /> );}
This isn't actually valid JavaScript. If you try and run this in-browser, you'll get a syntax error!
Because Webpack is orchestrating our entire build, however, it can take some liberties. In this case, it's allowing us to treat images as if they were JavaScript modules.
If we were to inspect the bundled output, it might look something like this:
const catSrc = '/public/assets/cat-a1b2c3.jpg';
function CatAvatar() { return ( React.createElement( 'img', { alt: 'Cute cat sitting in a chair like a person', src: catSrc, } ); );}
Webpack will transform the image import into a standard variable that points to where the image lives in production. By letting Webpack do this, we're able to let it perform certain optimizations, improving performance.
Similarly, Webpack lets us import CSS files, SVG files, all sorts of stuff!
The exact mechanisms and optimizations used are beyond the scope of this lesson. For the most part, these days, we can let Webpack do its thing without worrying about it too much.