 a second to set back down for those out there in the hall to come back in. So yeah, I'm going to talk to you today a little bit about Webpack and the awesome benefit that we've had at my current company in using it. So let me tell you first of all a little bit about myself. I work at Workfront. You may have known it as AppTask. In fact, I think in the conference website it says AppTask because it was when I submitted the talk a couple months ago. There's my Twitter handle in my GitHub repository. If you want to, I've got the sample code there at the end of my presentation. You're welcome to take a look at it or now if you want. That's fine. For the last little while, I've been at Workfront. It's been all front end. Most of the time in my career I've been doing backend development. I've been doing web development for about 15 years now. And about three years ago I made the switch over to be primarily doing front end development. And the reason why I wanted to do front end development was because of the challenges and growth that we see in the JavaScript community. It seems like all the real interesting problems, the real interesting challenges to solve were in the JavaScript community. And I think part of it is because of introduction of all the different tools and platforms that we've been given over the last few years. First of all, it started out with Node.js. And of course, we have IOJS out there as well that's helping competitions good. We add our build tools to that to understand how to take dependencies in our code and build our web assets together. We add to that our testing frameworks that allow us to implement unit testing. And yes, I very much like doing unit testing in my code. So I use these tools every day. The build tools that we have to understand tasks and orchestrating various build steps to build our deployables, send them out to Heroku, concatenate our assets, and all the other wonderful things that we do. We have all these wonderful tools. And that's what makes it exciting because these tools help us to further our development and help us to build really cool applications and help us to solve more important problems and these fundamental things. And of course, we have additional supporting tools that we've had for mocking and testing and asserting and all those other things. Of course, the tool I want to talk to you about today is Webpack. Webpack, as the title says there, is a module bundler. Its job is to take all our different assets, JavaScripts, images, CSS, JSON, all the other things that you might have that comprise a front-end asset and turn them into a static bundle. One of the first things we get as a benefit of Webpack, and I'll talk about a little bit more later, is a dependency graph. It shows us the benefit of meshing our code together by expressing the relationships through dependencies. A lot of times in JavaScript, I don't know if you've seen this before. Maybe you have, raise your hand, but take a web page and you have a dozen or so JavaScript files listed there, script source equals this, script source equals that. Who's developed like that before, where you have like 10 or 12 or whatever? I used to do that as well. And what's really important about those? You have to get them in the right order, right? There's some of them that have globals defined and additional other dependencies that if you don't get them loaded in the right order, then everything falls down. You get various things. Function is not defined and various other errors that you'll get in your dev tools that try to be helpful there. So expressing dependencies can be really important. That's the first thing I want to point out with Webpack. Expressing your dependency is important with asset management, and that's not just JavaScript. We'll look at it with other assets that we use in our front-end applications. Sometimes there has to be some shaping done on those assets that we have, and so just like the wood mill here, might have to do some additional shaping to transform them into something that can be put into a JavaScript bundle. And so we'll talk about some of the loaders and things that Webpack provides. Sometimes we have to be a little bit more aggressive with the type of assets that we receive, and so maybe a wood chipper's in order. And what we get out at the end is a nice bundle, a nice tightly bundled package of JavaScript and other assets that we can deploy on a static server or CDN or somewhere else in our application. Now, you might be asking, Jeremy, there's other tools out there that do things similar to what Webpack does. Those tools are good as well. I'm not here to start any kind of war about which one's better or more magical and eats jelly beans and makes rainbows and all that sort of thing. We're here in harmony today. I just want to tell you about Webpack, the awesome things it does for us and how it can benefit you in your tool set. So let's get started by building something in Webpack and see how that might work. Let's start with something a little bit smaller. So we'll go to our editor here. I have this really awesome file, Hello World, that I want to deploy onto this web page here. You can see a reference here in this page. Not a lot in here. It's just got one reference to a script source tag, bundle.js. And can everybody see that okay? Is size okay? All right. So I have the file there. This is entry.js and I want to go ahead and deploy it as index.html. Let's widen this out here. So I'm going to run one command Webpack, entry.js. And we want to output that as bundle.js. So it did some work. It generated a file called bundle.js. And if we open that file in our browser, we'll look at that amazing. We have Hello World on our page, index.html. You might be really amazed here, but really all we've done at this point or proven that Webpack can do for us is something as simple as this other command, or we can copy files. Great. We've got this glorified file copier. There's nothing more for us to learn here from Webpack. Maybe for all you guys know, I just aliased copy to Webpack and just for this talk. Well, there's a little bit more we can do here. So let's create an additional file. I was talking about dependency graphs and dependency charts a moment ago. So let's create a new file called content. We'll bring that up in here. So this is our blank file. Let's just say for entry here, let's get rid of the index.html. We don't need that right now. Let's take right here. Oh, we want this text right here to be customizable on its own dependency. So we'll just move that out into its own file. And we'll replace this. Notice I'm using module.exports, common js syntax. Just brings that constant or rather string literal of hello world out. Add to my entry. We're going to require that file in. These files are both in the same directory. We'll bring it in. Again, common js syntax. Let's run Webpack one more time. And you can see it's worked with two files here at this point. If I reload my browser, I've got an extra mark there somewhere, but it also says hello world. So I think I added that to my index.html. Look at that little tick mark. All right. So we've proven right now that we can load a file in. If we actually open the bundle down here below, you can see the exports and the various things that we did here. But you see all this Webpack stuff around it. It's actually fairly human readable, even though it does a lot of extra stuff for your file, at least in this mode. Let's do something a little bit more. But for me, it's a little tedious typing Webpack over and over again. So we'll just get a watcher going on this with the same files. What that's going to do is it's going to listen to files. Anything that's an entry file, like our entry.js is going to listen to that file along with any of its dependencies. And when those files change, it will go ahead and run the bundler again and put that together. So this should make things a little bit better. And in fact, let's try something like change this to Mountain West.js. Save. You'll see that the bundler just kicked off there. If we go to our browser here, we can see the change there. Nothing too earth-shattering at this point. But there's more here that we can do. We can also bring in dependencies from other third-party libraries. So I happen to have a library here that requires moment.js. It's called display time. Just say we want to add the current date and time to this page just for the purposes of our demo here. This is the file I want to use. One thing to note here in this file is I'm using AMD syntax in this file. Webpack by default understands common JS syntax as well as AMD. So you can take some of the existing AMD modules that you have. Like at work front, we have a lot of required JS that we've used, and so we have a lot of AMD syntax or files that are annotated with AMD. We can go ahead and take files like that and bring them into the system and Webpack understands them natively. Not only that, but it understands third-party dependencies over here in my project in the node modules. It's a little bit smaller than the rest of it. I have moment loaded as an MPM node package dependency. And so it's going to go ahead and look at my node modules to grab that file, that resource, bring it in, and that's going to do the action that's in this file. For us, we don't care whether it's in AMD syntax or common JS, we can bring it in the same way we bring anything else in. So if I wanted to add here, the current time is, and just require that file, can add that to the end. We'll see additional action happened here. It picked up the display time because, again, that's part of the dependency graph now. And it compiled that file. Let's go back to our web browser, refresh, and we can see our message here. And along with the current time with some poor spacing there that I did when I edited that. So let's fix that because that's a little OCD. That's going to bug me. All right. There's another thing that we can do with this is as you get more and more resources, you're going to want to open your DevTools and you're going to want to either use the debugger or you're going to want to go through and see where how things are working. Well, you can see here in the source, this is my bundle.js that it created. It's human readable, but it's not really something that I would want to look through and step through with the debugger and try to figure out which file has a mistake in it. And it makes it difficult for me to reason about. So we can add, there's source maps built into Webpack. So I can go ahead and take the line we ran before. There's a variety of ways to do this and a variety of configurations that Webpack supports, but I'm just going to use the default source map one. So we're running that. So a watcher is running, it's listening, notifying us of changes and building by the bundler. It's also generating a source map. So if I go back now and reload, yes we get our bundle here, but you'll see this little Webpack namespace down here below and expanding that out just following our same directory path. We can see our entry file that we had, our display time, and our content as well. And not only that, but we can add here to our display time. Let's just say we wanted to step through when it's going, we're having an issue formatting the time or something. We want to take a look at that. We can just add a debugger statement there. It rebuilt again, reload, and it hits the debugger, and you can see the location here. It's hitting the breakpoint that we just added into our code, the debugger statement. So it's very flexible to just want you to start getting, get going with some of those features. I mentioned earlier with our dependency graph, our web applications aren't normally just comprised of JavaScript. They're also comprised of CSS and other assets, JSON, images and whatnot. So let's add a little bit of JavaScript to this because white and black is kind of plain. So in this page we want to, let's just first of all create a new file here, collapse that, new file. We'll just give it a really awesome name like style.js, and, or style CSS, and we'll just style the body, let's say a font size, we'll double the font size because it's kind of small and we'll give it a background color of, I don't know, green, yellow. Now you'll notice that nothing changed here because we haven't added it to the dependency graph yet. So by simply requiring right here the file, let's start with that because that's how we've added things to the dependency graph up to this point. So add that to the top and run and it says, oh unexpected token, you need an appropriate loader to handle this file type. So of course it doesn't natively know how to handle CSS. We have to give it some things that will help it understand how to take CSS and embed it into our JavaScript assets. The way that this is done within Webpack is through the use of loaders. Loaders usually take some kind of input and they can transform them into another form here. We're actually going to leverage two loaders here. The CSS loader, I've already loaded them because I didn't know how the network access would be in here, but we're using the style loader and the CSS loader. The first, these actually read right to left, so you go back through it backwards. So it's going to run the CSS loader on it which knows how to read the CSS and bring it in as a JavaScript asset and then the style one here knows how to actually apply it to the screen. It says, hey apply the CSS to the page. So let's go ahead and add those transforms in there and you can see it's a building again. Let's see what it does to our page. Reload, it doubled our size there and added the background. This isn't very common JS style right here, adding these additional loaders. So another thing that we can do is we can put this into a configuration file where those transformers, those loaders can be added. So let's add ourselves a webpack configuration file. The default file name is webpack.config.js. And this is just regular JavaScript file. And what we can give it in here, we can give it a variety of things that we've been doing on the command line. We can give it the entry point and we can actually have more than one entry point which we'll look at momentarily. And we can give it the output. So let's just add those right from the outset here. Make sure that those are all working. And that's a minimal file. What that does there is that allows us to omit the config or mentioning the entry and the output file name on the command line and just it'll get them from the config file. So we just type webpack with our commands here. You'll notice here I'm using a dash D. That's for dev mode. What that'll actually do is do the source map, a shortcut for doing a source map as well as some of the other things you do during development mode. So I'm doing a watcher and a D here. We'll put that in. It's running the build and we can reload and it's still working. Let's just double check that it picked up my changes. That needs to be an exclamation point. So we'll change that and reload and we've got our exclamation point. So the thing, the reason why we added the configuration file in the first place is we wanted to actually move the loader functionality into a configuration rather than inlining it and our requires. The way that we can do that is through adding the loader to our configuration file. In the module section there's a thing called loaders. And what this is is we supply some rules here that tell webpack how to configure, how to work with various assets. The first thing we start with is a test and this tells it, it's usually a regex that tells it what type of file should have this loader applied to it. We're going to say anything ending in CSS. We want the loader and we can actually just take the exact same syntax we did on the other one and add that style of CSS there. Because we've made that change we can remove that from our file here and let's, we need to reload our webpack just because we changed the configuration. So let's start that up again. And the change is working. One of the things that maybe you haven't noticed but it's kind of tedious for me is I'm having to go through and refresh the browser every time I make one of these changes. Wouldn't it be nice if I could actually have it also refresh the browser when I make one of these changes? So what we're going to add here is a webpack provides a webpack, it's called webpack dev server. Let's just make sure that that works. I'm going to add some additional configuration here. This inline flag just adds it, it adds a socket IO library to the web page, embeds it in there that will actually listen for changes and knows when to reload assets on the page. That coupled with hot is our hot reloading. So we'll just add those to the page. There's some other things that we can add here which tells us our file progress and we all like colors. So we'll add that here. So it's serving up, you can see it's actually processing a number of files not just our entry files. It's also processing all the locales in the moment dependency we added. We'll talk about that more later. So we got our library here. We need to switch this to actually it'll by default it serves up on port 8080. So it's got that page here. Now as we make changes which the most the easiest one to show changes is to just show the CSS. It's going to go ahead and pick up our changes as we do that. And it also does that with any of our changes we make in here if we want to change the format of the time it's going to pick up that change and bring it in. That's kind of a brief introduction to what you can do with Webpack and kind of get in a basic development environment setup. That's actually about 80% of what you would do with Webpack. It's just describing your dependency graph, the various assets you want to bring in and applying the appropriate loaders to to make things work. But we can go a bit further with it and I want to show you a few other things that we can do, some tips and tricks that will help your Webpack experience go better. So let's see. So sometimes right just make sure I've got everything in a good place here. Clear some of this cruft out. Okay so we actually have a new project in here. You can see our Webpack configuration has changed quite a bit. As I mentioned earlier you can have multiple entry points. Many of us have multiple pages in there. Even though we develop a lot of single page applications there might be multiple sections within that application and so we want to maybe represent those as as separate smaller single page applications. This one here I have a grocery entry and a to-do entry. You can see the output here. We're just using one of the metadata variables that Webpack has called names. It'll just take whatever this key is on the entry and it will use that as the name of the output. I've given a little shortcut saying I always want source maps. So just generate those as part of my asset and I've added some additional loaders here. One in particular that's really useful now with ES2015 out there is is the Babel loader formerly 6-5 which allows us to transform our assets. We can write them in ES6, ES2015 and have them transformed into ES5 where we can actually consume them in most of the browsers out there which is really really cool. So let's see how that works. I'm going to get my Webpack Dev server running again here. In most of these command line settings actually nearly all of them can be put into a configuration. There's just some of them I prefer not to have in my configuration file because I'm also using the same file for producing production output. So let me just put those in here. Okay so we'll take a look at what this looks like. This particular app is pretty, is not very interesting. I've just got two pages, groceries where we can enter our groceries. Not too interesting and it has a to-dos page where we can, you know, model on, take a nap. I think that should be a task. Anyway, so you can add to-dos and you can check things off and it understands how to do that. Let's look at the code and see how that's set up. So here let's start the to-do entry. One thing you'll note here, we're using ES2015 all the way through. We're able to use the import here. By using the Babel loader it's able to understand that kind of syntax. So we're not constrained just by using, you know, the common JS syntax or the AMD syntax. We can also add this to our pages and of course we can use the other one as well. It just understands all three variations which is really nice. Here we're just creating, we're just importing that class in and creating it and attaching it to the body. It understands all of ES6 syntax or at least what Babel understands at this point. So we can bring all our dependencies in this way. We can use inheritance. All the nice things that you would want to be able to add with your ES6 stuff. One of the things that you'll note that I want to show with these change- oh the other thing I wanted to show with this is the to-do app is inheriting list app which levers the list model as well. That's where we're storing the code and really the only thing that's different between to-do app and grocery app is this root template. One of them says your to-dos for today using moment to format it and the grocery app that I showed before just has a different template that says your grocery app. That's really the only difference is that kind of that frame around the entire application. The list management, how they're stored, is all identical and it gets that through the inheritance here. Which means when we're loading a page here, let's look at some of these. Close that down here. So you start seeing some of these sizes. To-do app.js is 563k. It's pretty big. What do you think's the reason why that's so big? It's moment. Moment has all those locales that was loading in before. It's adding a huge demand to our thing. This is one of the downsides when we start looking at some of these tools like browserify and webpack is we got to be careful when we bring in third-party dependencies from node modules that we're not bringing in a lot more than we wanted to bring in in the first place. One of the ways that we can fix that, I'll show you in a minute, if we look at the groceries one, it's still fairly small here. It's 146, which is still kind of big for just the basic grocery app but it doesn't have the moment constraints. So let's take care of the moment one first and then see what else we can do. The first thing we can do is in our configuration, this is by default going to bundle everything that you described. It's going to traverse down that dependency graph and it's going to incorporate every asset that it finds and bundle it in. But we can give it some hints to say don't bundle certain things. So I'm going to tell it when it comes across moment and there's a variety of ways to do externals here. There's a map syntax and some other ways. There's ways to say, hey, when I get this variable in, it's on window.jquery, for instance. This is saying when I come across moment, window.moment is where I can access it. So in order to fix that so that we can actually get moment that way, I'm just going to add that script here. I think it's that one. I hope I get the right one on the first try. So it's serving. Let's take a look and see if the to-dos one, whoops, to-dos. It's always that plural. So it's getting the date in and let's see. So it's loading moment in and you can see our to-do app is much smaller. It's actually comparable in size right now to the grocery app. So we're able to reduce that. One of the things we want to think of is if we're hosting some of our third party modules, if you're using something like jQuery, if you're using something like moment or low-dash, things that are common, you may want to consider for performance actually hosting them separately, particularly if they're on a CDN. Leverage the user's browser cache or if you're using basket where you're storing them a local storage or something like that. There's a variety of options. The point is that we just changed a little bit of configuration and we were able to fine-tune our application to make some of those bundle sizes smaller. One more optimization we're going to do before I get off the stage is we can take advantage of some of the shared code options here. Now, as I mentioned earlier, to-do app and grocery app pretty much have the same code base apart from one little thing and that's their individual classes. If we require a webpack in and we use one of the plugins, there's plugins that webpack provides as well as far as how to configure our dependencies, how to optimize them. And one of them it provides is the called the commons chunk plug-in. What that will do is it'll look at the dependency graph, find commonalities between your various entry points and optimize those into a single file. So we'll do that. Optimize commons chunk plug-in and we give it the destination. We'll just call it init.js and then we just load a plugin section down here. Let's see here commons chunk plug-in. That should work. Let's see. You can see it's creating an init.js and you can actually see the size here that it created. These are very tiny now. The init.js is much larger than the other ones. Now, of course, in order to use those on the page, webpack is a module bundler. It's not a module server. So these are going to break because it can't find various things. You have to add the dependency to the page. Now, you can do this a variety of ways. There's tools out there like script.js, head.js, just script tags like this. You can actually use, you can package your stuff as AMD modules and you can use require.js on your page to host your files. There's a variety of ways to actually package these things. Let me fix that last one here. When we load that page, you can see the to-do stuff's coming up again. You can see this additional init added here that has the bulk of the code and the to-do app is very, very small. So if we had a lot of shared code, this something like the commas chunk plug-in can really help us out because as they visit one page, they're going to load that into a browser cache. They go to the other one. It'll be able to use a lot of the same assets. So there's a lot of benefits here. That comes from us using whether you use require.js, webpack, browserify, any of those out there by being able to define our dependencies, instead of defining them as globals, defining them in this nice dependency graph. All right. So other cool features that I obviously don't have time to present right now. They have image inlining. So one of the things that we've used is, I don't know about you, but we've used a lot of like sprite sheets and things. One of the things you can do here is by using the CSS plug-in with the image loader plug-in, you can actually inline your images using data URIs instead. If they're very small, you can get those in your CSS so they can be baked into the whole asset. There's feature flags where you can have kind of dev mode things. If you want to, like my to-do list, I could have used the, had some JSON staging the to-do list with some sample data. Well, it's in dev mode. Well, during production, I don't want to present it that way. The library output is really cool. Like I mentioned earlier, you could use require.js on the page to host it. You can output these using common.js, UMD, AMD, just a variable on the page. And if the, there's a variety of different ways you can actually configure the output to be generated on the page, so you can run it in a variety of configurations. At our work right now, we use AM, we've been using require.js on a lot of stuff. So as I'm building these node packages outside the main application of feeding them in, I build them in, with the AMD configuration and that way they can be bootstrapped in the application, even though I'm building them using Webpack. And finally, the testing story is really good with Webpack. There's a karma loader out there and pre-processor that we use. We've got Istanbul bootstrapped into it and so we get coverage, tests, all that stuff. Imagine the Webpack Dev server cycle that we've been doing here where it's kind of, as we make changes, we see them reflecting the browser. Imagine the same thing with your tests and you're instantly getting coverage, linting, those other things as well. It's a really nice development process. I really enjoyed it a lot. Just a couple of resources. There's the Webpack homepage, of course, Webpack.github.io. There's my repository that has some various tags in there that show the sample code that I showed here. This document by Pete Hunt is really, really good. I'm just showing how to use Webpack in a variety of ways. He covers some of these features as well and how they use it in practice at Instagram. So anyway, thank you for your time. Thank you for having me at Mount West JS. I've been told I have time for two questions. Right. Okay, so the question was, with externals, are you able to minify those? It depends on how you set them up. So one of the ways I showed there was to take the moment and just assume that it's a third party library and host it separately. The other way that you could do it, do that exact same thing is what I showed with the commas chunk plugin. You could actually build a separate chunk that has just your third party libraries in it, like a vendor module, if you will. And then those could go through the optimization and minification that if you wanted to host them that way. There's a variety of options. But with externals, it basically says something else is handling that. This is just how when I get a require this, I'm going to know where to find it. All right. I think everybody's ready to go. So I think another half an hour, right? All right. Thanks.