 Hello. All right, so who's ready for a crash course in Webpack today? Yeah. All right, I'm going to warn you right now. This is going to be a crash course in Webpack. And it's not necessarily WordPress focused. This is more like general Webpack that you can use in WordPress. So if you feel overwhelmed at the end of my presentation today, come talk to me. I'm really happy to answer any questions that you might have, or if you don't have a chance to chat with me, you can find me on Twitter. That's my Twitter handle there. Or send me an email or any other way you want to get connected. All right, so let's bow to the demo gods that all of this works out today. I'm doing a live demo. OK, so first let's talk a little bit about Webpack and what it is. At first glance, when I think about Webpack, I think it's kind of tempting to classify it like other task runners, things like grunt or gulp or any of the other ones that exist in the front end ether. Not unlike grunt, gulp, whatever, it can perform tasks such as compiling and minifying JavaScript or SAS. And it can do all sorts of processing of files, right? But what sets Webpack apart from the grunts and the gulps of the world is how it does that processing. So when you have a project and you have Webpack enabled or set up, what actually happens is when you set up your configuration, you basically tell it like, hey, I want to look at JavaScript files. I want to look at SAS. I want to look at images, right? And you have a certain entry point into your application. So in our case today, we're going to talk about this index.js file. That is the entry point into our underscores application. And when Webpack runs its processes to build files, what it's doing is it's looking at anything that's connected to this entry point. It's going to say, oh, hey, I see that we are using, we're importing navigation. So I need to care about that. Or I'm importing this skip link focus fix. I need to care about that. But if I have, say, the customizer, which we can see is in my JS folder over here, Webpack doesn't care about that because it doesn't know about its existence. So we're not going to waste time processing a file that we don't care about or Webpack doesn't care about. In the Webpack realm, what this is known as is a dependency graph. So Webpack just builds and bundles all of the files together that we actually care about and puts them into a separate folder for public distribution. All right, let's actually get started. So Webpack 4, which is the latest major version of Webpack, doesn't actually require any sort of configuration, which is really, really cool. I don't have Webpack installed globally on my machine, so you're going to see me type some really gnarly command here. So I'm going to type node modules dot slash dot bin slash Webpack. I'm going to hit Return. And nothing happened because clearly things aren't going to go right today. Let's see here. Womp, womp, carry. No modules. Thank you. I was looking at my notes like, what? Yep, typing, I tell you. OK, Webpack, boom. Something is thinking, all right, something happened. Great. So we can see something happened in the terminal, right? And what Webpack is doing without configuration is it's looking for something in a file called source or SRC. And it's going to look for an index.js within that file. When you type in your command to run Webpack, in my case, because I'm running it from my project, the node module slash dot bin slash Webpack, it actually produces this disk folder with a main.js. So it's without me telling it to do anything, it has actually gone and it has grabbed my navigation.js. It's grabbed that skip link focus and magically compiled it. Wow. I'd love to see grunt or gulp keep up with that magic. Sorry, I'm just so excited about Webpack. So we can see, though, this is kind of a nightmare, right? Like, what does this even mean, right? This is minified gobbledygook. This doesn't look like the old navigation I thought I had. I mean, I see one class name in there or one element ID. Sorry, that looks familiar, but the rest of it. I can't debug this. So let's jump in to actually creating our own Webpack config. And I think this is the scariest part of Webpack is when you get in there and you start creating your own config. So I'm going to go in here. And the first thing I'm going to do is I'm going to call in path and save it to a variable. Because Webpack kind of works in a node paradigm, we're using require instead of import. And path is actually a part of node. And it allows us to work with paths so that we can kind of give our node projects some sort of context, like, where are we working? Where should I run Webpack? This is why I don't have Webpack installed globally, because I don't want it to just run wherever it's installed. So that's what we're going to do first. And then we're actually going to set up our configuration object. Again, because this is in a node paradigm, we're going to save this configuration object to module exports. And the first thing we're going to do is we're actually going to set a context. So we're going to put in a context property. And I'm going to pass this dir name variable, which is a part of the path. And what this is doing is it's saying, every time I run Webpack from now on, like if I did have it installed globally, I want it to know that it needs to run from this project. So it's running relative to my Webpack configuration. So relative meaning within this underscores directory is where Webpack is going to start looking for files. So that's step one. The next thing I'm going to do is actually set up my entry point. Ironically or not, it's exactly the same as Webpack normally uses. It's going to look for source index. And then I'm going to define my output. And for this, you tell it what path you want it to live on. So I'm going to use that path variable that we saved. And then I'm going to type resolve. And then I want this to live in the root of my project, but in a folder called public. Great. So I'm going to save this. And now I'm going to make sure I get rid of that. OK, great. So now if I run that command again to compile Webpack, we can see some stuff changed. And now we have a public folder. Oh, I didn't give it a file name. Just kidding. Let me give it a file name, too. If you don't give it a file name, clearly it defaults to main.js. But you can actually give it whatever file name you want, which is super handy at other points in time. Like if you want to process lots of different files for lots of different reasons, there are great things you can do here. So I'm actually going to call this bundle.js just to kind of differentiate it from what we have by default. I'm going to just blast that away quick, run again. And now we can see our public folder came back. We have bundle.js. Oh boy, we still have minified files. So this isn't particularly helpful. If we had some sort of problem in one of our source files and we needed to debug it, it's near impossible to do so. So what we're going to do now is go back to the Webpack config and actually add a mode. So we already know that Webpack, by default, is trying to run, well, actually is running in production mode. So every time you run that process, it's going to compile and minify your JavaScript. So now what I'm going to do is say, hey, Webpack, I actually want you not to run in production. I want you to run in development. So now, when we run Webpack and we check out our bundle, hey, Prasto, we have something that is now human readable. And this still isn't great, right? I think if I remember well, somewhere in here, I have a hello world kind of just chilling, right? I want to be able to track down where that is. So the best way to do that is to work with source maps. And what source maps do is they take the code that we write as the humans, the source code, it takes that and it maps it to that bundle.js that Webpack actually produces. So we're going to go back to Webpack and we're going to say, all right, I want you to add a dev tool. And we're going to add source map. And if we run Webpack again, we can see now in our public folder, we have this bundle.js. And when we look at this, I realize this is quite small. So I will make it bigger once it reloads. We can see, oh, hello world is in our navigation file, on line 54. So if I wanted to track that down and remove it, I can do that now. So this is just like basic setup. Webpack is capable of doing so much more. So now let's move on to talking about loaders in Webpack. So as we've discussed so far, Webpack can understand JavaScript by default. It's able to compile JavaScript files that are connected to that entry. It can then minify them. And that's about it. But even when it comes to handling these JavaScript files, I mean, if you're a developer, you know that not every browser has the same ability to handle modern JavaScript, modern CSS, whatever. So if I have stuff, and I do have things like arrow functions, for example, here's an arrow function in the navigation file, where I'm saying, hey, I want to use some modern JavaScript here. Or I have a for of loop down here. I want to be able to use all these new fangled things in our latest versions of ECMAScript, whether that's ES6 or ES2035. Doesn't matter. I want to be able to use it. So this is kind of where loaders come into play. Loaders help us, where it helps Webpack do things that it can't do out of the box. So they extend the functionality of Webpack to allow it to do more processing, whether that's taking JavaScript files that are written in ES6 or further in the future, or if that's working with SAS files or SCSS and actually compiling those into normal styles, like CSS, that can be read by your browser. So what we're going to do now is we're actually going to add a loader that will take this for of, it will take this arrow function, and it will translate it into something that some of our older browsers, for example, IE11, the bane of my existence, will be able to understand. And this is also true for things like React. React, you need more than what I'm going to show you with the Babel loader, but kind of the same premise, like these loaders and these kind of ideas are what makes our modern JavaScript, our modern CSS, accessible to all browsers. So what we're going to do is we're going to add another property. It's called module, which is an object. And within that, we're going to add an array assigned to the property rules. And within this, we create objects for each loader that we want to use. And this is where stuff gets terrifying. So the first thing I'm going to do is I'm going to have a test property. And what this test property is going to do is it's going to, I'm telling it, hey, webpack, I want you to look for all files that end in .js or .jsx. And if you've worked with Regex or you're terrified of it, you might want to cover your eyes. I don't know. At the core of it, we can do just this. This is a Regex that will only look for .jsx. Actually, let me add the dollar sign. That's going to look for anything that ends in .jsx within our project. But if we were writing a React app and we were using .jsx, we could actually go in and add question mark x. And that's just saying, maybe look for this x. Maybe not. So Regex can be a thing that is terrifying. But just add what you need. And the next thing we're going to do then is actually just call our loader. So I'm going to call babble loader. I have all these things already installed so that we could kind of keep this moving. But that's all we're going to do. This is all you need to tell webpack to be able to translate ES6 and further in the future into ES5 or something else that can be understood by older browsers. So again, we're going to run webpack. It did its thing. And now when we pop open our bundle, if we look for that button.onclick, it's still an arrow function. What did I do? Live demos. I tell you. Let's see here. Just get rid of that just in case that's the problem. Let's see, we've got module, we've got rules, we've got our test. All right, let's try this again and hope it actually changes. OK, a thing happened. Ah, there we go. It did work this time. It didn't like my regex. That's why regex is evil. Lesson learned, right? Next question. Thank you. Yes, I get confused. I usually look these things up to validate my assumptions. OK, but we can see that our onclick function now is no longer an arrow function. It's instead a standard function that any old browser can understand. Just like that for of that I had just below that is no longer a for of loop. It's actually just a standard for loop in JavaScript. So again, even IE11 can understand this language. Great. So I think one thing that you might have noticed is rather annoying and cumbersome is trying to remember this node module slash dot bin slash webpack, or even just having to type it every time I make a change. So what I have done is in package.json, I've actually added these two, or I have an entire scripts object in here. But the two that actually matter are the first two. We have the build script, which is telling, it's saying if I run npm run build, it's going to run webpack, and it's going to run it in production mode. So it's going to go ahead and minify the files instead of creating the big old human readable thing that's got all those extra comments. So we can just test that really quick by running npm run build. It did a thing. And now when we look at our bundle, that's so great. I tell you, these live demos, I don't recommend them. It's like it's caching. Oh, maybe it's just trying to open something that I don't see here somewhere. Nope. Well, normally it works. So that's a little discouraging that it's not working correctly right now. But it should be running typos. It normally works. So I just need to double check that. I have this on GitHub, and it does actually work. So there's that. Aim, it should. No. Yes. Yes, this does override it. Let me just test. Dev is running fine. So I probably typed something slightly wrong. No, it won't. No, the command line arguments will always override what you have in your configuration. I'm pretty sure I just have a small typo somewhere that I'm not seeing. You know what? Nope, I think the equal sign is it. Good call. Whoever. Helpful. Audience angel. There we go. Thank you. You know what you're talking about? Maybe you should come up here and finish my talk for me. Yay, look at that. It worked. All right. And the other script we have is the dev script. What this is doing is it's running webpack. We pass it this watch parameter. And now whenever we make a change in any file that's connected to our entry point, whether that's index.js, navigation.js, or the skip link focus fix, every time we save one of those files, it will automatically update. So if we go back and rerun npm run dev, we kick off this watch process. The main reason I can tell it's working is because I don't have my standard prompt anymore. And then I'm going to just say come in here, type something very basic. We can see a little magic happened here. And if we go into our thing here, we can see, oh boy, it actually output that console log statement. So we can see that's actually working correctly. So that's great. The thing to keep in mind, though, is if you're still tweaking your webpack file, you can't keep running in development mode or in watch mode. And that's because webpack isn't smart enough to know that it needs to update a process that's already running. It's process, or its brain is tied to what you had when you kicked off your webpack process. So I'm actually going to kill this process. And we're going to move into talking a little bit about plugins. And I think this is what makes webpack confusing. We have this idea of loaders. And then we have this idea of plugins, and not to mention all the other options and possibilities that are in between. To me, plugins of webpack aren't too dissimilar from loaders. They fill in gaps in our build and bundle process by doing the work that loaders can't. So for me, when it comes to actually working with webpack and working with that loaders and plugins ecosystem, my first instinct is to see, is there a loader that can do this? And if I can't find a loader to do the job, then I'm going to look for a plugin to do it. So now we're actually going to add a plugin to our webpack configuration that is going to hook into that dev process so that every time we save a file, it's going to reload the browser as well. So it's not just going to update our source code or our bundle, but it's going to reload the browser so that as we're coding along, we can put in console logs for days or do whatever we want. We'll be able to see that feedback immediately in the browser. So when we work with plugins, usually what you need to do is you need to declare some sort of variable for the plugin at the top. So we're using the browser sync plugin. Webpack does have its own dev server. It's a pain to get to work with WordPress. So I recommend just don't go down that road. You will waste your time. It will not be. It's just not a good use of your time. The browser sync plugin, it's a plugin that's quite common in gulp and grunt processes as well. And it works exactly the same way with exactly the same options. So if you've used browser sync before, you'll have no problem setting it up in Webpack. So I'm just going to require that and save it. And then what we're going to do is we're going to come down in here and we're going to add a plugins property, which is an array. And in this array, what you do is you instantiate your plugins by typing new. We save this to browser sync plugin. And then some plugins don't take any options. So you can simply just type new whatever plugin and you're good to go. Browser sync does take options and where you want to use them. So the first one we're going to do is add files with an s. And unlike our tests in the rules for loaders, this is a globbing pattern. There's a difference. They're both confusing. I'm going to look for anything that ends in .php. And then what I'm going to do is I'm going to add my proxy, which is my local development URL. So I got underscores.test. Save that. And now what we can do is kick off npm run dev. All right, so we can see a few things happened, right? We can see now instead of it just kind of stopping here, we get this new bit of information. This is telling us that browser sync is active. It's currently proxying my local URL underscores.test. And then we can see that we can access it at localhost colon 3000. And you can see it also popped open a new browser tab with that particular URL. So now what we can do is have a lot of fun watching things change as we're actually going on. So I'm going to pop open my console. I'm going to just move this down to the bottom. I'm going to make this a bit bigger. And then we can do like can't type. It just works. It's wonderful. It would be way more impressive if I actually had some CSS hooked up and then I could change the background color to hot pink and offend everybody's eyes. So all right, this has been literally the just fastest, easiest intro I could possibly give to Webpack. This barely scratches the surface of what Webpack can do. And actually, let me real quick, in a pop open, a real world example of a Webpack configuration file I'm using on a day-to-day basis. To me, Webpack, once you kind of take the time to get to know it, it's actually a little bit easier to configure than Gulp. I know Morton was talking about WP Ray earlier and how it's using Gulp. I've looked at that and I still am like, but how? This doesn't make sense to me. And then I look at what I've got going on with Webpack and I'm like, yeah, this totally makes sense. I know what's going on. But there's so much more you can do. You can have multiple entry points. And this is super helpful when you're working with Customizer JS or Admin JS. You can actually split out minified bundles just for what you need and where you need them. So you can on cue only the Admin and the Admin and only the Customizer and the Customizer and only the front end on the front end. Wow. We can also process more or different types of files. You can compile your SAS. You can compile. You can do more than compile SAS. You can actually work with SVGs. You can work with images to minify them and process them. You can do a heck of a lot more even with just the loaders. And then you have more plugins that will give you even more functionality. You can lint your style files or work with your SVGs. Whatever you need to do. So this is actually written in Webpack 3. So it's a little bit more verbose. I think the example I finished for the underscores for Webpack is much smaller. I think it's less than. I mean, in total, this one's only 126 lines. I think the one that I created for this underscores repo is maybe around 80. So it's not much shorter, but it's a little bit shorter. And there are some really great plugins that are a lot more understandable. So that's enough of me ranting and raving about Webpack. Who has questions? I'm not entirely sure. I've never tried to install it on a server. I do all of my development for WordPress locally because I am terrified of breaking production. And I don't think my employer would be happy with me if I did. So I'm not entirely sure is the answer. I don't know if you can actually run Webpack on the server. Any other questions? Go ahead. So when it comes to determining whether you should use Webpack or whether you should use Gulp, I'll be straight with you. I love Webpack, but if you're familiar with Gulp and it does what you need it to do, use it. Don't switch just for the sake of switching. That is not good for your productivity. It took me, I would say, like a good six months to get really comfortable with Webpack. And that's through trial and error, trying different loaders, trying different plugins, seeing how can I build something that mirrors my current grunt process. I was using grunt previously. The advantages you do have, however, is if you decide to introduce React to a theme, then you can do that. I mean, adding React, having your project understand React is a heck of a lot easier when you're using Webpack. I think it's possible to do it with Gulp. I don't know how. It's a little bit faster as well. So I used to work at Web Dev Studios, and we used to work on really huge enterprise-level client projects. And you'd sit there and you're waiting for a browser sync to do its thing or whatever. And some of those processes could literally run for seconds. Ain't nobody got time for that. So if you're having problems with just your productivity is being affected, then maybe it's worth considering a switch or, at the very least, reconsidering your build process. Any other questions? Go ahead. There are a lot of different resources. I think the Webpack documentation is terrifying, but it is robust. Like I said, even this fully flushed out version of my Webpack config is still only barely scratching the surface of what Webpack can do. So if you want to get information overload, go there. But I mean, there are other things. If you want to use different source maps, you can do that. You can see what those options are for configuration. I learned Webpack, actually, through a little bit of trial and error, but there's a really great course on Frontend Masters by Brian Holt. It's his intro to React, version three, not the latest one, because he's not using Webpack in that. Even if you don't want to pony up the 39 US dollars for a month, they have all of the transcripts for each video for free. You just got to know where to look. But he's got a really great kind of intro to that there. And I should also mention, I have a companion post that goes through the full buildout of this Gnarly Webpack file. On my site, it's hopefully live now. If it's not, it will be soon. You can go read about how I built out an entire process that works and get up and running yourself. And there's also the projects available on GitHub. You'll have to just go to the feature Webpack branch to have a poke at the Webpack configuration. Any other questions?