Webpack Plugins System Creating a Webpack Plugin
Transcript from the "Creating a Webpack Plugin" Lesson
>> Sean Larkin: The first place that we wanna start, and remember when I describe the anatomy, is that a plugin is just an instance or it's a class that has an apply method. So let's create one and build utils and we'll just call it, MyFirstPlugin. Now if you're publishing this as a node module.
[00:00:20] We have a naming pattern that's always whatever name web pack plug in, right. Because there's thousands of different plug ins for different systems. But so like let's just call it MyFirstWebPackPlugin.js. All right, so first and foremost is the common JS module. And so, module.exports equals, I'll just leave that there.
[00:00:42] We can actually just say MyFirstWebpackPlugin. And you IDU will throw errors, like, I don't know what this is, maybe. And then we can create this class, right. So what are the rules? Just has to have an apply method on the prototype chain, or in this case on the class
>> Sean Larkin: Now what we get passed to it is the actual compiler itself, right. So we can provide compiler there and let's see will be the most, okay. So now we could technically add this plugin to our configuration and just run it. It should just work, nothing's gonna happen, but it should run.
[00:01:29] So why don't we do so? And so let's go ahead and jump into our config. And now we just need to require this file, right. Because we're gonna pass it into the plugins array in our configuration. So let's see, I would probably say cons MyfFirstWebpackPlugin equals require, and then relative.
[00:01:52] So I think we have to go into build utils, right. Utils MyFirstWebpackPlugin cool.
>> Sean Larkin: Now we'll actually go ahead and pass that in. And remember it's a new instance so my let's just do this so it's easier, MyFirstWebpackPlugin.
>> Sean Larkin: Okay, so let's just run our code. It doesn't even matter what environment, I'll just say dev, like yarn dev.
>> Sean Larkin: It looks like it's gonna work. Feeling good about it, boom. Now of course, we didn't do anything. We don't have any functionality, but this is the first step, right. This is the first step in creating your plugin. So what do we wanna do? So there are some hooks that are only specific to the compilation, some that are only specific to the compiler or watch mode.
[00:02:50] It's like if we are in you own dev we wold need to hook in to run base, like watch base hooks. So I think what I wanna do is maybe do something like, when Webpack is done building the files, we just console log, right. So we would say complier.hooks.
[00:03:07] Now, we can't see the hooks right now, like, in our intellisense. But hopefully by the time we are done adding our JS dock invitations into our source code, you can actually see that. But since we know how to look in the source code and it's not scary we can just jump into webpack/compiler or webpack source compiler.
[00:03:29] So let's go find it in our nerd modules, or like, I already have the source code here, so compiler.js. All right, so what hooks do we have, find this.hooks, oops, there we go. Okay, so there's one called done, that gives us the stats. After omit, we could do it as it's emitting files to disk.
[00:03:55] Let's just use done, at's an async hook, and we know that, because it's called AsyncSeriousHook. And so the last argument is gonna be a callback, in addition to the data it passes here. So, let's go ahead and start with that. So, we'll say hooks.done and then we'll say capasync.
[00:04:17] So, that's the API for tapping in. And so the first argument, like I kinda told you in the slides is gonna be the name of your plug-in. So MyFirstWebpackPlugin, there we go. And then second one, we saw that we were gonna stats out of it, right. So stats, and then a callback because it's async.
>> Sean Larkin: So what I like to do so I don't forget, because web pack just stops working if you don't ever call back is I just put the call back at the bottom. So now we can technically, why don't we console log the stats? It might be kinda huge, but let's just do it anyways.
[00:04:54] So now let's go ahead and just run, so we could run yarn. So I guess if it's done, watch mode won't work. So why don't we do, yarn prod? Cuz it's never done until you cancel the process, right.
>> Sean Larkin: I have a feeling we're gonna see a lot of things output to the console [LAUGH].
[00:05:17] My, okay.
>> Sean Larkin: So we can actually see, look, it's all of our data here. Now do you know what would be even more valuable than just console logging? I did teach you something at the end of day one, remember that?
>> Speaker 2: Debuggers within.
>> Sean Larkin: That's right, let's do a debugger here.
[00:05:41] And we have a command, don't we? Yarn debug prod, oops, I think it's just debug, cool. Now, I can open up Chrome. Now if you, go ahead and open up Chrome, I'm gonna cheat a little bit and I'm gonna attach to VS code, okay. So you can step through until you get to that hook.
[00:06:14] Now it was a little slow, right? So if we're looking in the terminal, well there we go, it just console logged, right. So now we're stopped right at the debugger. And this will look the same for you even if you were in Chrome and you went to the dedicated tools.
[00:06:29] So now what's really neat is like, cool, I can actually explore what's in stats and everything. So I can see like, what is stats, stats it's a class, it has the Webpack compilation instance. It tells us the start time, the hash of the entire build cuz my packs completely deterministic.
[00:06:47] So you get a unique hash for whenever you build for a scenario of all the stuff. Like what else do we have in here, we got all the chunks. The chunks is just a file abstraction right that we put modules in and optimize. We have any of the entry points used.
[00:07:06] Stats basically contains everything, all the information about your build. Now it is serializable, like we have a stats.2json. So if I called in our debug console or stats.to, yeah, there's even three methods on it. So I can call it tostring.
>> Sean Larkin: And look what it outputs. It's the terminal output, that is the output.
[00:07:32] That's what we do when we run Webpack, we just call status a string. Now, what's cool is that I think you can even pass, like you could say, verbose, let me see does that actually do?
>> Speaker 2: Yes, that makes it verbose.
>> Sean Larkin: Thank you, verbose, syntax here are great.
[00:07:51] Yeah, it's thinking about it, here we go. It's going to like destroy the buffer. So this is how we control like what kind of What kind of stuff we output, right. So if you do and this, I'm just doing this internally in the console, right. So stats, that two string verbose, like this actually shows you a lot of information.
[00:08:16] It shows what kinda bailouts happen? Why did tree shaking maybe not occur? What kinda module types they are? What kind of import specifiers and syntax's? You can learn everything about your build with this. And this actually corresponds to our CLI flag dash dash ribose, that's how we know and that's how we call it.
[00:08:39] That's what the CLI is doing behind the scenes. So I think maybe, what would be cool, what would be nice to actually know about? So I think what would be cool, I think somebody was telling me, what if we don't create an HDMI file, what if we're writing a custom plug-in?
[00:08:55] What if we need to have something to inject into a blain template or a razor template, right. Or what's a kind of a templating language that you use for server site development? You guys can just call one out, what's a good example? XAMEL, rails use ERB I think, but anyways, for us to do that, just like HTML Webpack plug-in, we would need to know, well, what are the admitted assets and how are they grouped, right?
[00:09:24] So stats.compilation.entrypoints can do this.
>> Sean Larkin: So if evaluate this and we look, we get a map file and we get all the entries. So we can say stats dot compilation dot entry points dot, I think you can just say like ray dot from? How's my jaw discript foo, cool.
[00:09:57] And you can leverage this information. So you know that one it's your main entry point. And like there's all sorts of information on the entry point itself. It tells you what chunks correspond to, it tells you what files, and so there is that. You can also search like stats.cmpilation.assets, I think this one is very commonly used.
[00:10:27] So maybe we'll write a little quick plug-in that will just cancel log the names of those files, right. Let's just do that, I think that's great, that's a great first opportunity. So, I'll just step out of debug mode, and we'll just jump to our file. And so we know that stats.compilation, let's see, it's an object where the key is the name of the file.
[00:10:52] And it looks like the value is the actual source code, right. We just obstructed into a class or asset name in stats, that compilation dot assets. I think four N is the right there, not four of, is it four of? I always forget, we'll find out. And then lets just say const asset names, some array.
[00:11:26] Lets say assetnames.push, asset name And at the end we can just literally say console.log.
>> Sean Larkin: Beautiful, heck, let's get fancy and join it with a line return and see what happens. All right, so now technically we don't need to break into our code. We could if we wanted to, to be sure, but let's just run yarn prod again.
[00:12:34] So something that's common for us at Microsoft, is that we have this system called Appex,. And it's just a compressed file, but it has a manifest.json of file names. And it lets us create, like, a UWP application out of, just like Apedo UEA like a web app. And so, but it's like in XML, and it's the worst format ever known to man.
[00:12:57] And so it's not a manifest JSON, manifest XML. So this is valuable because the build time we can generate the manifest needed with all the assets that are gonna be in this zip file.