Reviewing webpack config0:00
Alright, moving on, so I've tweaked our webpack.config.js file just a little bit to keep things not too overwhelming. So we have our entry, our output, we have some basic rules that you might want to follow, watch for JavaScript, intercept any loading of a JavaScript file, and apply Babel. And then we have a minimized plugin here. And then we have this one from a lesson or two ago, where we just create a plugin on the fly, where we listen for when Webpack is finished compiling, and when it's done, we write a file that contains a stringified version of the stats. So if I were to say npm run dev, we are then going to get a disk directory that contains the manifest.
Switching to dedicated plugins0:35
So if I were to say npm run dev, we are then going to get a disk directory that contains the manifest. Okay, well, let's talk about creating dedicated plugins instead. Like I said, what we have here, perfectly fine. No issue whatsoever. But if you're curious about how to get from here to maybe something like this, well, let's see. If we're going to create our own, and by the way, there are dedicated manifest plugins that I would recommend you use instead. This is just for a learning exercise.
that I would recommend you use instead. This is just for a learning exercise. Okay, so we're going to create something. What would it be? Maybe like a manifest plugin, maybe build manifest plugin. So we can comment all of this out and get started. As our first step, we're going to pull this in. So var buildManifestPlugin. Let's put that within maybe a build directory, and then plugins, and then build manifest plugin.
Let's put that within maybe a build directory, and then plugins, and then buildManifestPlugin. And I'm using var here, but usually I use let. Lots of people use constant or const. I don't know. I just don't like it. I stick with let. All right, so let's create the file. build plugins, buildManifestPlugin. Now, all Webpack plugins are going to take a basic shape.
Webpack plugin structure1:37
Build plugins, build ManifestPlugin. Now, all Webpack plugins are going to take a basic shape. You're going to have a general ES5 constructor, so build ManifestPlugin. And then you're going to have an apply method on its prototype. If you're not familiar with the prototype, I assume you are. But if you're not, think of it as adding a method that will be shared and not duplicated across all entries of the object in the instance. Okay, so you're going to want an apply method that will accept the Webpack compiler. Now you can use this compiler to hook into any number of events. So if you want to listen for when it emits a particular chunk and then append to it or
Now you can use this compiler to hook into any number of events. So if you want to listen for when it emits a particular chunk and then append to it or add your own chunk that will be emitted, you can listen for that. If you want to listen for when Webpack is done, as we've already reviewed, right down here, then you can listen for that. So there's dozens of events. Finally, of course, you're going to export your plugin. And this is the basic shape that all Webpack plugins will take. So once again, create your constructor, then add a apply method that Webpack will trigger on its own.
So once again, create your constructor, then add a apply method that Webpack will trigger on its own. And then finally, of course, export that. So now, within our webpack.config.js file, we import our custom plugin, and then wherever is necessary, we new it up. And of course, if you need to pass through any variables, you would accept those here. Then you assign it, standard stuff here, and then you can reference it whenever you need to. All right, let's undo that a few clicks though. So to start, let's just console.log and say yay to make sure that we are triggering this.
Implementing manifest plugin3:04
All right, let's undo that a few clicks though. So to start, let's just console.log and say yay to make sure that we are triggering this. So I'm going to run npm run dev, and yay. We triggered our plugin. All right, so now at this point, all we have to do is fetch our code from before, switch back and paste it into our apply method. But now rather than this, we're going to call plugin off of compiler. So we're going to say compiler, I want to listen for when you are done compiling, you're going to give me the stats, and then I'm going to write a file. So I can say let fileSystem = require('fs').
going to give me the stats, and then I'm going to write a file. So I can say let fileSystem = require fs. And then, well, here, this is still going to fail, I think, if we give it a shot. So we run it, and boom. Path is not defined. Okay, well, that's a different one than I expected. So let's do it again. And we should boom again. Yeah, see, it's trying to create the manifest within that build/plugins directory because that's what we told it to do.
So at this point, of course, if you just want to clean things up, you could say, listen for when you're done compiling, and then write the manifest. If we want things to be nice and clean, let's do this really quickly. Write manifest, that will accept the stats. And then here, I can get rid of all of this and bring it down. We're just cleaning things up, being good developers. And that should still do the exact same thing. Now, maybe one other thing you might want to do if you are building this is, well, if we run it again, you're not going to see the mix manifest file show up in the output here. So we would have to do that on our own.
Emitting a custom asset4:53
we run it again, you're not going to see the mix-manifest.json file show up in the output here. So we would have to do that on our own. And what you might do is you could listen for the emit webpack event. And then once again, that would accept the compiler. And what you could do is something along the lines of saying compiler.assets. And then you're just going to add your own custom asset here. Now, if we make that equal to a simple object, and I'm sorry, this should be compiler, this still isn't quite enough. So if we give it a run, webpack just doesn't do anything. And that's because it will look for a callback.
So if we give it a run, webpack just doesn't do anything. And that's because it will look for a callback. So we can accept the callback here. And yeah, this is basically our way of saying we're done with everything we need to do. So move on, and you can get back to work. So if we run it again, now we move on to the next step. And yeah, here's the issue. Webpack's trying to prepare this asset for us, but we didn't give it the source. So what exactly should be the source, the source code or the contents for this file? I'm just going to return foobar for the time being.
So what exactly should be the source, the source code or the contents for this file? I'm just going to return foobar for the time being. We give it a run, and I think it'll do one more blow up for us. And it's going to let us know, well, I don't know how big this file is. So what we will do once again, let's say size, and then I'm just going to hard code it for the time being. And if we give it another run, this time I want you to note that we did push to that asset. So once again, without that, it doesn't emit the asset. It's not there.
So once again, without that, it doesn't emit the asset. It's not there. But in this case, we do emit it. Now remember, when we emit it, it's literally going to create that file. So for example, if we got rid of this entirely, where we actually write the manifest and we start from scratch, run it again. And now you'll see that you still get manifest.json, and it contains your file. So for general plugin development, this can be really useful if you need to add or extract additional files. This is the pattern that people will take.
additional files. This is the pattern that people will take. Which means if we were to come over here, I could now just come up to our source, and we're going to return something along the lines of that. But now we don't have access to stats. Let stats, and then we'll say compiler. Get the stats for me. And then we'll reference that object, convert it to JSON, grab all of the assets, and then stringify that. So once again, if we run that, switch over, now we've achieved the same end result, but
stringify that. So once again, if we run that, switch over, now we've achieved the same end result, but we did it in a slightly different way. Which means I can now remove this part entirely. Now for the size, we can just get the length of characters if we want. So maybe let the manifest will be that. And then we can even clean this up by saying compiler. Just don't worry about the temporary variable. Like so. Then we can return the manifest there, and then the length of the manifest.
Why publish plugins7:29
Like so. Then we can return the manifest there, and then the length of the manifest. So just the number of characters. So we give that another run, and this will now be determined dynamically. And once again, if we take a look, we have exactly what we started the video with. So you might be thinking, well, what's the point of doing this? It was so much more work. Usually you'll do this if you're creating a plugin that will be distributed to other people. You're going to put it up on NPM.
people. You're going to put it up on NPM. It needs a lot more functionality. And you don't want to tell them, well, just spit these 30 lines of code into your Webpack configuration file. You want to wrap it up, give it a nice name, and they can just new it up and everything will work behind the scenes. All right. So I hope that's been a good review. If we even switch over to the Laravel Mix project, you can see that in our source plugins
So I hope that's been a good review. If we even switch over to the Laravel Mix project, you can see that in our source plugins directory, there's quite a few different plugins here, and it's the same thing. It's a way to hook into Webpack to add any additional functionality whatsoever. So for example, even something as simple as this, a buildCallbackPlugin. So we new it up in our Webpack configuration file. And then when Webpack applies it, all we do is listen for when Webpack is done. And then we trigger your callback, which means if you put this in your own project, you would then be able to say right at the bottom, let's get rid of all this, and you could say new buildCallbackPlugin.
