Webpack 2 Deep Dive Webpack 2 Deep Dive

Exercise: Extracting CSS Part 2

Check out a free preview of the full Webpack 2 Deep Dive course:
The "Exercise: Extracting CSS Part 2" Lesson is part of the full, Webpack 2 Deep Dive course featured in this preview video. Here's what you'd learn in this lesson:

Kent reviews why the CSS is first loaded into a JavaScript module and then extracted with the ExtractText plugin. He then answers a couple more audience questions before concluding the exercise. The solution to this exercise is on the FEM/06.2-extract-css branch.

Get Unlimited Access Now

Transcript from the "Exercise: Extracting CSS Part 2" Lesson

[00:00:00]
>> [MUSIC]

[00:00:03]
>> Speaker 1: So it's taking your CSS, putting it into a JavaScript module and then adding that into the link, adding all of the-
>> Kent C Dodds: Yeah, so, I see where you going.
>> Speaker 1: I'm confused what the advantage of this is on that one.
>> Kent C Dodds: Let me explain how this works, so.

[00:00:27]
>> Kent C Dodds: Yeah, and by the way, we can now get rid of that. And it totally puts the links up at the top and the scripts at the bottom, just like where it should be. But, yeah, so this is how it works. And first off, there's a loader portion.

[00:00:42] What this is doing is it's taking some configuration and returning a function. And the function is a loader, so loaders, they're simple as a function that takes some source code and returns the resulting code. Whatever that is, it doesn't even have to be code, it doesn't have to be a string, it could be an object, it could be anything.

[00:01:00] And so in this scenario, it's saying, give me a loader that's going to take all, like any file that comes through it is going to go first through the CSS loader, and then whatever it needs to do to become a JavaScript module. So, the CSS loaders, it's not just taking the string and making it a JavaScript module.

[00:01:25] It's also resolving all the URLs for images and creating a base64 string for small images and taking care of fonts and stuff. And so once it's all done, then the ExtractTextPlugin will take that module and take the CSS and stick it into a styles module. Or, yeah, our CSS file.

[00:01:46] And then the plugin, the ExtractTextPlugin, well, that, sorry, I kinda got ahead of myself. The plugin is what's responsible for taking those modules, and making a file out of them and removing them from the bundle. So, now the string and all the other object portions of the CSS are no longer actually in the bundle.

[00:02:09] Webpack doesn't bundle those because the plugin removes them. And so, yeah, to answer, I think the question you were gonna ask is why wouldn't you always see this? Is that maybe what you're gonna ask, or?
>> Speaker 1: Kind of, I'm looking at this from a perspective or historical use, lots of Gulp and Less, and Webpack is seeming more and more opinionated on how everything needs to happen.

[00:02:35]
>> Kent C Dodds: Sure.
>> Speaker 1: And, it's great for JavaScript, fine, I'm having a hard time making that transition to saying that I also want Webpack now to handle all of my CSS. And if it's already in Less, then there's another transition that's happening there. So I was just curious as to what the advantage was if there was one for performance or anything?

[00:03:01] I mean-
>> Kent C Dodds: Yeah, yeah, so it's not necessarily a performance advantage. And once you use the ExtractTextPlugin, [COUGH] it's also not a performance disadvantage, it's kind of the same as far as performance goes. And the benefit that you get is explicitness in dependencies. So, with Gulp and Grant, building your CSS, I should have talked about this a little bit earlier, but.

[00:03:29] Well, just to kind of think about it holistically. You have components, whether they be Angular components or React components or Backbone views, or whatever. Those things consist of three very, very important things. The markdown for them, whether it be JSX or HTML or whatever, the CSS used to style them and the JavaScript used to control behavior.

[00:03:50] If you don't have one of those three things, then that component is worthless, right? So, they are, they are coupled. It's impossible to get away from the idea that they're coupled. A lot of people were used to thinking them like separation of concerns, but it's not at all separation of concerns concept, it's more of a separation of technologies.

[00:04:09] And that's where React comes in, they're like yeah, why not put your markdown right in the JavaScript file? Not a big deal, right? And in fact, it's got a lot of power to it as well. And now there's the CSS and JS movement that's yeah, why not put your CSS in there?

[00:04:23] Because they're already coupled, just marry them. And so, yeah, one of the really nice things that you get from Webpack as treating these things as modules, is now you can make, you can make this coupling explicit, and make these dependencies, so that you can perform analysis on them.

[00:04:45] But even more important in my mind is they're associated together in code, and in your brain when you look at the code.
>> Speaker 1: Is the CSS getting directly associated with the specific JavaScript in HTML that you're needing other than what you're putting into your Webpack file?
>> Kent C Dodds: Good question, so I mentioned I wasn't going to talk about CSS modules, but that's one solution to kind of enforce this.

[00:05:13] And so, [COUGH] and I used to use CSS modules a lot. I don't use it quite as much at all anymore, but one cool thing about CSS modules, all that you really have to do to turn this on is in your loader, you can say modules = true, I think.

[00:05:30] Or you can also provide this as an object where the name, I think, is CSS, and the query: {modules: true}. Something like that, you'll have to look in the docs. But with that kind of configuration, then you can start writing your CSS, well, actually, this is valid CSS modules.

[00:05:58] So, I have this toggle-graph. And now I can actually import toggleGraph. And what the value of toggleGraph will be is the class name that is actually generated. So here, we'll say from. And so now, I can use this somewhere, if I was creating a class or something, I could say toggleGraph.

[00:06:19] And then just parse it, and now that dependency, not only is it explicit in the sense that I'm importing you, but it's also explicit in the sense that I'm importing something from you. Yeah, super, super powerful. I really like the CSS and JS movement, but if you're not doing that, do CSS modules.

[00:06:38] Yeah?
>> Speaker 3: So, Angular 2, you can now import or actually just write your CSS inline.
>> Kent C Dodds: Yeah.
>> Speaker 3: Is this extracting it from that, or does it still have to be in a CSS file?
>> Kent C Dodds: I'm not sure, actually. I imagine that there will be a solution for it, because enough people are gonna be doing that, that they want to solve this problem.

[00:06:58] But I expect that right now, it's still a problem to be solved.
>> Speaker 3: Okay, cuz when you say extract text, it's like, yeah, it's like extracting it from-
>> Kent C Dodds: It's extracting it from the bundle. They probably shouldn't have called it that, because that's like calling it based off of how it's implemented, which isn't really right?

[00:07:16] Probably should have called based on what it does for the user. Yeah?
>> Speaker 4: So, this might be an artifact of what we're just talking about, but looking at those two files. Styles.app.css, contains all of styles.vendor.css, plus the extra toggle stuff.
>> Kent C Dodds: That's not what I'm seeing in mine.

[00:07:38] So, maybe we can look at it later and see maybe there's something different.
>> Speaker 4: This is from your extract CSS.
>> Kent C Dodds: So you just checked out the branch and ran it? That is interesting. Well, maybe there's a bug in here, and I'll fix it. Meet up with me after, we'll figure it out.

[00:07:59] I'll make sure that it's working when you all go home. But yeah, it doesn't do that normally. [LAUGH] Okay, cool, yeah, another question?
>> Speaker 5: Did you answer the question, can we have two ExtractTextPlugins for both SASS and CSS?
>> Kent C Dodds: Yeah, good question. So, I haven't tried this, but I have had multiple loaders for CSS, and doing something like this.

[00:08:26] If you were to do exactly what I just did where you copy one and paste it, where you have two loaders that have a test that matched the same file, what you're gonna have is double loading, and that can do some really weird things. So, it probably would break.

[00:08:41] So yeah, you want to make sure that if you are double loading, that's not necessarily a problem. For example, if you wanted to use the eslint loader, then you could do this, that would totally work and be totally fine. Probably better to just do this instead, have it run through eslint and then the babel loader.

[00:09:03] But yeah, you could probably have one was like .css and a .sass, or whatever. And then that would go through the, well, actually, you'd have a couple loaders here, and one of them would be the SASS loader, and the other would be CSS. And then that would be loaders.

[00:09:28]
>> Speaker 4: Other way around, [INAUDIBLE]
>> [INAUDIBLE]
>> Kent C Dodds: Yes, you're right, other way around. Don't look at the man behind the curtain, yeah, be something like this. I expect, yeah, good question.
>> Kent C Dodds: So, yeah, and Scott L is asking if anything would be in vendor? And yeah, this has all of the common CSS for like to do in MVC apps, I mean MP4 that we had before.

[00:09:58] So, it basically has the content of this file. It's pretty much, I think that's all that it has, based off of our entry, where the vendor, it's just that one file.