Webpack 4 Fundamentals

Webpack Bundle Walkthrough

Sean Larkin

Sean Larkin

Webpack 4 Fundamentals

Check out a free preview of the full Webpack 4 Fundamentals course

The "Webpack Bundle Walkthrough" Lesson is part of the full, Webpack 4 Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:

Sean examines step-by-step the Webpack runtime, which is the loading and resolving logic needed to connect modules as they interact.


Transcript from the "Webpack Bundle Walkthrough" Lesson

>> Sean Larkin: I'm gonna step through this code really quickly. So what's the first thing that you see here that's glaring obvious? You're like, whoa, this is a common pattern I see anywhere dealing with bundling or shipping code of the web in encapsulation. It's one of the first things we talked about, do you guys see that?

It is an IIFE, right? We have an IIFE. Okay so, when I read IIFEs, contextually, what I wanna see is, where's the end, and what's being passed into it, right? Because that's our state, that's our scope, that's all the data that's gonna be used inside this IIFE. So, we know that we have an IIFE, and what's passed into it is the variables called modules.

We don't know what it looks like yet though, so let's just dive to the bottom. Yeah that's right, I forget, we decorate this on purpose. So the ending of these bar comments, that's where the end of the IIFE is. Well okay, so here's the end of our IIFE, and we know the variable is called modules.

So what do we have here? Inside of it, is passed an array, right? So we have an array and here's the end of the array. And what do we have here? An array of?
>> Speaker 2: IIFEs.
>> Sean Larkin: [LAUGH] Look at that, we have an array of IIFEs. Okay, cool.

What do we have? It's our actual code, right? We even use these decorations to try to make it easier for you to understand. So if I was to just pop a console really quick, we have 0, 1, 2, 3 as our IDs. Well look, 0, 1, 2, and 3.

So we get an array of IIFEs that is passed into this code right here. So we call this the web pack bootstrap, some people call it the runtime. I've heard people call it the manifest. I would not recommend thinking of a manifest like this because it confuses the whole PWA manifest, and all that kind of stuff, I don't think that's helpful.

So I usually call it the runtime code, cuz our internal APIs basically say, chunk.hasRuntime, and this is what the runtime is, okay? So let's just understand exactly what this code does. We can just take it step by step. So if we're starting at the top, so we have a variable called installedModules and it's just equal to an object, right?

And so what do we think this does? And the comment even helps us. It's a?
>> Speaker 3: Cache.
>> Sean Larkin: It's a cache, it's a cache, it's a module cache. We don't really know how it works yet, but we're gonna find out. Okay, and now we have, at the top level, a function called webpack_require.

And so this is the require function. So let's just look at this. I'm even gonna zoom in, so contextually we're only focusing on just chunks at a time, right? So it's gonna be hyper large, super large. There we go. All right, so what is this code doing right here?

>> Speaker 4: Checking whether or not a module exists in the cache.
>> Sean Larkin: That's right, that's right, exactly. And you'll see that webpack_require takes a module ID parameter, right? So when this function's called it's gonna have some sort of ID passed to it. And that's where we get this. So basically we're checking in the object, which of course we know right now has nothing in it.

And then if it already exists, right, we're gonna return that existing reference, right, and its .exports. It's exports. Don't confuse this with the real module semantics. This is how we're making it work in the browser. So we have defined .exports, kind of. And you'll see this here in a second.

So .exports, so it's gonna return a property called .exports from whatever is inside of this module cache. So now if we look down below, so of course that was an if statement, so if the module if doesn't exist that doesn't happen, right? So you can forget, nothing there's yet technically.

So we see module equals installed modules, and then we actually put it in the cache at the exact same time as we declare, is equal to the module ID that we passed, right, from here. And then, I can't remember what the false means, I can go find out.

And then there's a property called exports, which is an object, right? Okay, so that's a good start. So, then, I'll zoom out just for the sake of seeing the entire context here, just for this line. So now, we actually need to call the code that we've required, right, cuz we're still just inside this one require function.

So, we go and find that module. Right, so we'll go pick it out. We'll do a .call. We take the exports, and then we're also gonna pass some other things inside of this IIFE, cuz right? Our models are an array of IIFEs. We'll pass the existing required function so that in case that module is using other modules, and then we are also gonna provide whether default or named exports.

That's right, L means the module has been loaded, right? So it's set to false by default but then once it's actually executed we're gonna set to true. And then we return the .exports property from this synthetic module that we're creating. So that's what web pack required us. So keep that in your mind, it takes an ID, and it actually calls the module and then returns any exports if it's available.

So, and then we also have some other stuff here. Now, so ESM uses what's called live bindings. And that means that it's basically a feature supporting cyclical dependencies, so natively it's gonna be implemented inside the browser. This is the code required to be able to implement it in just JavaScript print.

So basically what we're doing is we're freezing the object so that it can't be reassigned or changed. That's why we wrap it in an object defining property. If you need to support IE8, you need to have the object.define property shim. You'd find that out pretty quickly. And then this is for common JS interop, right?

So, common just technically doesn't have a default export, it has modules that export. So what we do is we aligned with TypeScript and Babbel to provide this pattern so it's consistent. And then there's some other getting different, also compatibility, for non harmony modules. But the meat in the potatoes that are super important is the webpack_require.

So if we go down to the bottom of the this code now, the last line that gets executed, what is happening here technically? So if we look, now that we know what webpack_require does, somebody tell me what that line does? [COUGH] Ignoring the .s. The webpack_require .s is not as important, but what's the ID getting passed through?

>> Speaker 4: The first module.
>> Sean Larkin: That's right. That's our entry point, executing. We're executing our entry point. The first module in the bundle itself as well. So if we look at the IIFE we know now, so modules is actually modules that gets called, we're calling this function here which isn't IIFE.

We've passed this information in, which is like scope and state, and then the require function and now what's happening is that it's calling it on the other things. So you can kind of see how your code resembles the userlang code, if I compare the index up next to it, it's not quite the same.

But you can kinda see, right? Cuz we're pulling out the nerve, the footer, the button and the styles. And we try to give it some sort of understandable name. And you can see here that's why we're pulling it. And since they're different modules in different locations we actually have different IDs.

So, webpack_require 1 is just jumping down here and calling this. And in the same way, require 2, webpack_require 4. So how it works is that webpack_require is just replacing these import statements, the require statements, to something that actually works in the browser. Execute and behaves the same in the right order.

Does that make sense so far? Do you have any questions? I know this code at first, the generated code can be a little intimidating, because it's like how is this only five files and I have this ginormous, what is this? And I get some people who just try it for the first time and they're scoffing, they're like this is way bigger than my original code.

But of course you know thousands of modules, tens of thousands of modules, much more optimized. So this is really the minimum overhead that you incur from using webpack, but everything is done at build time, right? So this is is the only runtime code that exists from webpack, everything else is just a product of the build.

But yeah, any other questions or anything?
>> Sean Larkin: I would always recommend, this is a great place if you just wanna learn how things are working. It's nice even debugging the set mode none because you can actually see, we even identify hey, this is a harmony import. Hey, this is a default export.

Hey, this is a harmony binding, because we're binding a function, right? So it shows. It shows you all this just in comments. We can identify that. And it's kind of using the same heuristics that we used to do tree shaking.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now