Check out a free preview of the full Web Performance with Webpack course
The "Dynamic Code Splitting Walkthrough" Lesson is part of the full, Web Performance with Webpack course featured in this preview video. Here's what you'd learn in this lesson:
Sean walks through an example of dynamic code splitting.
Transcript from the "Dynamic Code Splitting Walkthrough" Lesson
[00:00:00]
>> Sean Larkin: So yeah, exercise time.
>> Sean Larkin: So let's go ahead and I'll take and I'll check this, I'm just gonna check out a branch really quick. But what I want you to do while I'm doing this is take, and let's add, let's say I think a great example would be to leverage button styles, right.
[00:00:22]
Let's just say instead, go ahead and create a folder called button-styles, well, we'll just do it together. And inside of it, create a module, one is red.js, one is blue.js, each of the colors. So red.js, blue.js, green.js,
>> Sean Larkin: yellow.js, okay, that seems pretty good, that's fair. Okay, now let me just stop where we're at and check this code, so let's see.
[00:01:14]
>> Sean Larkin: Check out 0501,
>> Sean Larkin: Good,
>> Sean Larkin: Awesome, okay, so beautiful, hopefully that pushes, great. Okay, so back to where we were, so now let's take button-styles.js, and really, what we're just gonna do here is, each of them will just be a default export that uses the same pattern.
[00:02:03]
So we'll keep this existing module in, cuz we don't wanna break where we're at right now. But we could even start our dev mode and get the incremental changes and feedback from webpack as we're trying to do this. So blue would be default, our export default.
>> Sean Larkin: "color: blue", all right, seems kind of nice.
[00:02:31]
Got a little duplication here, or I mean a little repetition. But I just wanna make this easy to understand, "color: red" and "color: yellow".
>> Sean Larkin: Here you go.
>> Sean Larkin: And so once you've created these four, let's jump back up into our index and let's see where we have applied it.
[00:03:07]
So typically, we're applying it, let's see, from,
>> Sean Larkin: I think what's kinda cool is, maybe we should do it inside of the unclick, right? So like when we click on the button, let's set a new color style, that's pretty nice. And we can still use the existing module, right, to set our initial.
[00:03:27]
And so what we're gonna do now is, we need to conditionally load this. So we are going to write a function that says setButtonStyle, right? It can be anything you want, but we'll say setButtonStyle equals a function that returns a dynamic import, right? And so we need to provide webpack with information to know where to resolve these modules.
[00:03:56]
So we're gonna do path to button-styles, and we do need to use template strings. Now you can do concatenation of strings, I just think this is so much more convenient to use the back ticks. Oops, what's interpolation again, there we go, slash, and then,
>> Sean Larkin: Color, or we can say color, these variables can be named whatever you want.
[00:04:32]
>> Sean Larkin: Now when we save this, look, you may have noticed in your first rebuild, you instantly get four more bundles created, right? And they're tiny cuz it's a small module.
>> Sean Larkin: But that's great, let's now actually use it, so we can say,
>> Sean Larkin: getButtonStyle, is it setButtonStyle, there we go, setButtonStyle, and once again, it is just a promise.
[00:05:04]
But now we can actually provide the color, so I'm just gonna say red.then, and then we can say style name or style.
>> Sean Larkin: And then,
>> Sean Larkin: button.style = style.
>> Sean Larkin: I almost feel like it's easier to say style string, I just hate seeing the same name here.
>> Sean Larkin: Now let's jump into, we can pull up the dev server if you don't have it loaded.
[00:05:52]
>> Sean Larkin: Reload our page, and hey,
>> Sean Larkin: Doesn't look very red.
>> Sean Larkin: What I should do is actually console log this, so we can see what actually this value is, style string.
>> Sean Larkin: All right, so let's jump into our console, this is that debug driven, if you're not really sure, what is that actually set to, right?
[00:06:25]
>> Sean Larkin: The default is color red, so it looks like I just need to access the default, right? I always get thrown off from this, export default color red default, okay. So I would technically, what's even cool is that you can send a debugger statement here. So this is probably one of my favorite parts, is now I can hit this, I can stop and I can literally just see what this statement is.
[00:06:51]
So looks like instead of just calling the style string, I should be saying styleStr.default, right, so.
>> Sean Larkin: At least that's what it looks like here.
>> Sean Larkin: So maybe this is a case where it's like, maybe I should, I'm just gonna rebuild.
>> Sean Larkin: I love using debuggers when it comes to code splitting cuz it's like, cool, now I can inspect everything that I have here.
[00:07:22]
Step through, watch it get set, boom.
>> Sean Larkin: Instantly based on runtime conditions. Well, you could set some random runtime condition and say, if window.whatever, or atEventListener on some event. But what's cool is that we didn't actually need any of the other lazy loaded chunks. Right, they're created and they're provided there in case they're called.
[00:07:54]
But the value is, we only needed to use this one, and therefore, that's what got loaded up. And you can reuse this in your code now, you can have this as an individual module that you pull in and pass anywhere. The key thing about using this kind of dynamic code splitting is that you always have to pass information.
[00:08:16]
Partial path, webpack won't know if this is just a variable, I'll just say color, and this is gonna error. I'll get a warning and it says, hey, the request of a dependency is an expression. The point, what this is trying to explain, we need to make this easier to understand this warning message.
[00:08:35]
But the point here is, and you'll learn a little bit as I talk about how webpeck works under the hood. But if webpack has to resolve a dependency, what can it resolve when you just pass it a variable? It doesn't even know where to look and find the code, right?
[00:08:52]
So it has to do it statically, and that's what the partial path is aiming to provide. So does anybody have any question before I move on to magic comments?
>> Sean Larkin: Well, I think this is a really awesome technique. I think maybe before we move on, the only other thing I would say is, this expression right here, what webpack does is, it just uses a regex and separates them out.
[00:09:19]
It says, okay, this is the partial path and then I'm looking for this. Now you can even do something like this where if you said .js, if you had a folder that had a bunch of other assets in there, webpack would try and resolve those and creates bundles for them.
[00:09:32]
Right, especially if you have the loader to support it. So adding the .js would filter and say, only resolve the .js files. And that's probably I think is the coolest thing. For example, we support JSON out of the box, right, and JSON is by default, resolvable. So if I put in here, I actually think this is really cool too because these wouldn't even need to be JavaScript files if they're just strings.
[00:09:59]
Right, you could literally say magenta, or no, let's just say pink, pink.json. And let's see if I index, okay, yeah, so that's right.
>> Sean Larkin: I'm just gonna reload the dev server. Okay, so if you have paint.json in here, [LAUGH] replace of undefined.
>> Sean Larkin: I've never seen that error before.
[00:10:37]
>> Sean Larkin: Yeah, because there is no JSON in it, sorry. And if I said,
>> Sean Larkin: I think if I said default, right? And then I said, let's see what the color, pink.
>> Sean Larkin: [LAUGH] It added another lazy loaded bundle, right? So here, I'll just redo the dev so we don't see the incremental update, we'll just see the all the bundles initially created.
[00:11:14]
>> Sean Larkin: Look, now you have another one, right, because webpack by default can resolve JSON, web assembly, .mjs and js. Those are the four extensions it supports. And so it's gonna resolve this because there is no partial path. And so if we jump into our dev mode, and I actually tried to call this, or maybe I'll jump it into, here we go.
[00:11:38]
If I said set button color to pink,
>> Sean Larkin: Instead let's see what happens.
>> Sean Larkin: So we gotta reload, okay, great.
>> Sean Larkin: You hit the button, I get a break point, and look at what we have in here. We actually have the default, if I console log it, style string.
[00:12:14]
>> Sean Larkin: So it looks like I could just have it be, now with JSON, it's a little bit different cuz we force everything into a default name space, right, and so each property is its own export. So in this case, we have a named import of default, but look, you can do that.
[00:12:28]
And so the point is that you can be more strict about your filters, and you can say, webpack, don't try and resolve this and create a lazy little bundle for it, okay? So if I just set to js, then it's not gonna emit every single bundle for it.
[00:12:49]
>> Sean Larkin: So that's how you just make your context resolving more strict. So that, I think, is probably one of the coolest capabilities, is that you can be really expressive with it, even though it's not truly dynamic. So okay, I'm gonna just commit this really quick, and then we're gonna talk about magic comments.
[00:13:13]
That was something that I saw a lot on our feedback, git add src.
>> Sean Larkin: 0502-context, here let's see, not-so-dynamic-code-splitting [LAUGH].
>> Sean Larkin: Okay.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops