Learn Webpack - Full Tutorial for Beginners

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
everyone this is cold welcome to my web pack YouTube mini course thing there's a couple things I have to get out of the way first the most important one is that there is a github repo that goes along with this course so if you follow along if you want to see the code I mean I do type every line from scratch so it is a true code along but if you just want to check the code out at any point use this repo view it in the browser there's a bunch of commits with nice detailed messages clone it down if you'd like to use git if you feel comfortable checking out each commit and I'll reference throughout the video you know I'm on commit 7 going to commit 8 and that sort of thing ok the next most important thing I know everyone's gonna ask why am i wearing a hat I need a haircut ok and I thought this was better than the alternative you see what I'm working with here yeah okay so on to the course content this video is about web pack in general so if you already know how web pack works what it does what the point is then you might want to skip this or just fast-forward through it in the next video we start with installation so because it is 10 videos I did decide to spread things out instead of just rushing through everything so I will not take offense if you speed through any videos or skip them that's what the github repo is for as well if I were taking this course I'd probably just start by looking at the code I've always liked to do that before I watch any videos ok so let's get going let's talk about what web pack is this is the web pack homepage and I like how this image explains it web pack can be very confusing and intimidating and cause many headaches when you're actually setting it up and configuring it but its mission its core goal is very straightforward it takes a bunch of different assets different files of different types javascript images like SVG P&G JPEGs CSS stylesheets or less or sass all sorts of different files and it combines them down it bundles them into a smaller group of files one file maybe or one file for your JavaScript one for your CSS one for your third-party JavaScript to vendor j/s and one for your app code app jeaious it's very configurable which is where it can become a little tedious and pretty intimidating to people who are learning it but the idea behind it is very simple so in addition to just bundling things together and just shoving them into a file it's also managing dependencies it's making sure that code that needs to load first is loading first so if you write a file that depends on three other files those three need to be included first so often it's a very complex web of dependencies and larger apps and it would be very difficult to manage it on your own web pack does it for you and it spits out one or two or however many files you tell it to bundle and I like how the github repo explains it web pack is a bundler for JavaScript and Friends packs many modules into a few bundled assets and through something called loaders which we'll talk about modules can be commonjs es6 CSS images json CoffeeScript blah blah blah blah blah the list goes on so we're going to see how to do a lot of this stuff but first I want to show you an example of an app that is already built we'll be creating our own from scratch and configuring web pack but this app is substantially more complicated way more dependencies than what we'll be doing in this course so this is an app that I'm building for my upcoming react course it's a a color pickers website so there's a bunch of color pickers you can click on one you know you can copy a color there's a whole bunch of features things like changing from hex to RGB to RGB a all of that involves a library that helps figure out colors and and convert between different color types I'm using a library to get these nice sliders and this little snack bar thing that pops up down there there's transitions I'm using the react router Rose my point is there's a lot of different stuff going on that is third-party code that I'm depending on there's some code to help with drag-and-drop there's code for a color picker so I can create new palettes reorder them I save it and there's code in addition for this emoji picker here so I can select an emoji anyway that's enough with the app itself but it's sufficiently complicated where I think it makes sense as a good example for web pack so if we take a look at the code there are I don't know 20 something JavaScript components or react components that I've written plus 20 something CSS files plus a whole bunch of dependencies lots of modules things that I'm using like react color I'm using this emoji Mart I'm using material UI react of course some form validator libraries there's a lot of dependencies and this is for a single file and there's twenty-something of them so at the end of the day each one of them has at least this many dependencies and it's very tricky to determine what needs to load first if I was manually including script tags for each one of these 20 files it would not be sustainable so this is built on top of create react app which is a pretty standard way of creating new react apps and it uses web pack behind the scenes in addition to some other things but web pack is really responsible for the bulk of the functionality behind create react app so it's going to take all of my JavaScript and combine it into one file it takes all of my CSS and combines it into one file it does a lot more involving things like babel for example but at its core that's what it's doing it's bundling my assets and making sure that it's managing the dependencies so if I wanted to run the application I can run NPM start which will run it in dev mode which starts a local server but it still uses web pack and if I open up the chrome inspector you can see in sources there are MC just a couple JavaScript files bundle J s and then main chunk J s and this contains all of my code combined into one file there's some weird stuff going on if you're trying to read it using eval basically each one of these is a single file that I wrote a massive string and it's being wrapped in a web pack module and this is keeping track of what it exports and what it depends on and you can actually see for example this is mini pallet J s okay that's one of the components and if I keep scrolling over you can see things like this web pack imported module 6 equals web pack require of react so web pack require is how web pack is keeping track of what is imported where what needs to be exported what uses what basically manages dependencies so it replaces my imports and exports with these web pack requires so if I kept going it's pretty annoying to scroll but you'd see ok web pack required mini colorbox that's another component that this component imports it relies on that component and what might surprise you to learn is that it's actually importing all of my CSS as well into this file so it didn't make me a separate CSS file because I'm running in development mode and I'll show you just a moment what it does in production and now if I instead decide to run this in production which I'm not really going to run it I'm going to export I'm going to spit out a build folder so npm run build this is a command with create react app you'll see that it makes me a couple of files once it finishes it can take a while which is why we don't export these CSS files in development when we're constantly changing things because it takes forever to recompile it to reap undal okay so that's just finished and if we start by going to my text editor scrolling way up close this down here there's now a build directory and inside of that build if we look at our Java Script there's a couple files there's these source Maps we can ignore but they're all minified now this is the same stuff i was looking at earlier when I was using the dev version but now it's been all crammed together and minified and I have separate CSS files but if we look at them they're all of my CSS separate files have been combined into one and also minified so web pack is doing all of this for us again it's managing dependencies it's bundling code together and now if we look at index.html which is somewhere in here there's only what to script tags at the bottom and one or two link tags at the top instead of 20 or 30 or 50 separate script tags that I would have to do manually okay so hopefully that makes it clear what web pack does why you would want to use it it's a huge headache on large apps to try and do something without web pack or something comparable alright so I mentioned this in the intro video but I want to bring it back up in case you missed it or you skipped right to this video so you could start installing stuff which I get by the way but I want to bring it up because this repo is very important for the rest of this course the next 9 or so videos it includes all of the code and all of the commits that I make in all of those videos so the link is in the description it includes detailed commit messages I'll talk about in each video which commit I'm currently on so I do type everything from scratch it is true code along but if you want to reference the changes I'm making or if you get lost or you just want to look at it without the video click on a commit and you can see the diff you can also see the notes I've written up top and if you're more comfortable with it then and just check out each commit as you go all right so this is the initial state of our application a very very simple app that we're going to add web pack into and configure it a couple different ways and you'll see it gets surprisingly complicated just to do a couple of the basic things now that's not a dig at web pack it's just maybe a bit of damage control on my end just to let you know that this stuff it can be annoying or difficult to follow which is why I gave you the github repo so that you don't have to type everything yourself if you want you can follow along that way but you can also just you know check out each commit as I go and you'll be able to see what's happening so the code right now is the initial commit there is no web pack it's a single index.html a single app j/s file and an SVG image so you can see here's our HTML there's a single script tag at the bottom fjs has 40-something lines imagine that it's 4,400 lines instead of 40 and that will help make it clear why web pack really makes your life easier once you get it set up at least okay we also have some content of course and then I'm using bootstrap from a CDN so unchanged eventually we'll actually be using local bootstrap we'll be writing some sass to override different variables change colors in bootstrap and then use webpack to bundle it all together and make it work but for now it's coming straight from a bootstrap CDN unchanged and this is what the app looks like when I just open the index.html I'm warning you it's extremely simple and not exciting we have two inputs styled with bootstrap I can add numbers together by clicking only adding unfortunately and it prints out your result down here so some simple JavaScript and some extremely simple validation if I put numbers I mean letters in here instead of numbers I get this alert styled by bootstrap that says please enter two valid numbers a ASD is not a number blah-blah-blah-blah-blah is not a number so it's actually really horrible validation because you can cheat it as long as you have a number in that string so this is going to be one plus 12 which gives me 13 even though those aren't valid numbers but that's not really the point the content of the code doesn't really matter much it's more about just having javascript that we break up having some sass having some CSS having an image that's what really matters so don't get too hung up on that because the same stuff I'm going to show you will apply to more exciting more complicated applications but I wanted to make something simple enough to follow along with okay so the first thing I'm going to do is break my code up into separate files so that will take us into commit to if you're following along that will be the second commit so there's a couple things that I can break up from my app j/s first of all we have these different functions I'm going to put those in their own file each one in its own file in a utilities or utils directory because we might want to use those somewhere else in the app in checking if inputs are valid checking or parsing inputs that's functionality we could use somewhere else also you know we're just breaking it up so that we have something to bundle it's not very fun to bundle a single file I'm going to make actually I'm going to refactor our code to have two services an alert service and a component service and then I'm going to have a function called run that actually starts all of our code so I'm going to do that now I'm going to make a new folder inside of source called app and then inside of that another new folder called utils and then the first utility will be parse - input CAS and I'm just gonna cut this code right there and put it in this file and then I'm gonna do the same thing for our second utility function which is called inputs - R - valid is and I'm going to cut this out and paste it in right here there we go and I'll fast-forward through some of these changes but I'm going to make a couple more files just so you can see the file names in the app I'm gonna have alert service is I'm going to have a component dot service J s and then I'm actually going to move my app j s into app so I'm going to delete this when I'm done okay so I'm going to fill out these files again it's the second commit if you want to see how I broke the code up for yourself okay so I'm back this is the alert service a class called alert service I just moved the code into this it relies on inputs are valid for example we also have component service which doesn't have any dependencies so far and then inside of app J s the real the new FJ s I'm going to delete the old one that's outside of my folder now it's just all in this app folder so I have my utilities two functions and then I have alert service component service and then app J s is going to instantiate new instances of alert service and component service call them alert service and component service and then it has a function called Run which accepts an instance of alert service and component service and I'm calling that at the bottom so this is what actually starts the app everything else is just a function definition or a class definition but this function run is what actually runs the code what starts everything so don't get too hung up on the code it's not really the focus all that matters that is that we have code spread across different files so now my index dot HTML needs to change because I'm linking to the old app J s but now it's inside of the app directory so source / app / FK s that should get me that file but you probably can tell already this is going to be problematic if I try and run it refresh the page there's an error alert service is not defined okay so this is sort of a heavy-handed way of proving a point that managing dependencies is tricky it's not so bad in this example but we have alert service we need to make sure that that has loaded first we need to use component service before we can run this code so app J s depends on those two but then we have alert service which itself uses inputs are valid so we need to make sure that it's aware of inputs are valid right now all that we're actually including is a single script for app J s we have to manually include every other file so I'm gonna do that now I'll fast forward okay so I now have all of those scripts but once again I need to change the order because some of them depend on one another so app J s I'll just put that at the bottom because it depends on everything else loading first and now are we good to go let's see okay it's working so that's a very simple example but if we have a thousand dependencies or a thousand file and each one has ten different dependencies or something like this from the previous video this react app that has 20 something react components each one has a bunch of dependencies at the top here's a different component a whole bunch of other dependencies so if we're trying to manage this ourself it's a nightmare which one loads first instead we use webpack okay so we're not using webpack right now we're doing it manually and the point is that it sucks so we're now going to install web pack so this is the end of commit - right now if you're following along commit 3 includes installing web pack and getting it up and running so that is what I'm gonna do right now ok so to install web pack the first thing we need to do is actually set up our package JSON so I'm gonna do an NPM in it I'll do - why just to make it faster it doesn't ask me all those questions now I have my package JSON and I'm gonna begin by adding to my kit ignore the node modules directory just so that I'm not committing that you don't have to do that of course and then in my package JSON where'd you go I'm going to get rid of this scripts for now we'll be adding our own script in just a moment so we've got name code that's fine I'm gonna set private to be true again doesn't impact anything as far as web pack but it just prevents it from being published on NPM okay now what I'm going to do is install web pack so NPM install - - save dev web pack and if I just did this it would actually prompt me to install a second package which is called web pack - CLI the command-line interface and we want that as well we want both of them so this sometimes takes a little bit so I'll be back once it finishes okay so that wrapped up now we have both of those dependencies in our package JSON next we're going to set up a script inside of this scripts portion the scripts property of our package sell JSON and we'll go with start so when we run NPM start from the terminal it's going to call web pack just like that that's actually all we have to do for now well we'll change this we're going to configure web pack but out of the box this will work and we can actually give it a shot right now well we're gonna run into a few problems so before we configure webpack we will be configuring it and telling it all sorts of different things that how it should work how it should handle certain files where it should put certain files how many it should bundle when it should name them bla bla bla bla bla but by default when you install it and you don't configure anything you don't have a configuration file it has a couple of default values and we can actually see one of them if I just do NPM start right now it's going to call webpack you can see right there where are you web pack but if you look at the error it's telling me it can't resolve dot slash source so it's actually not the most clear error but what it's saying is it can't find index j/s inside of the source directory the default entry point that it's looking for what it's craving is an index jeaious file instead of source and the reason it says dot slash source instead of slash index afterwards is because when you require an entire directory and node the index J s is what is used by default so it's not finding it so it's not happy so let's make an index J s inside of our source folder index is this is where it's going to look let's add an alert hello from webpack well save now let's see what happens when I run NPM start once again by default we didn't configure it it's looking for that file so we made it now it's also saying something about a main j/s it built our code into main jeaious ok and there's also a warning down here we didn't set the mode option so it falls back to production we'll talk about that later in this little mini course so if we look there's a new folder I did not make this folder manually it's called dist and there's a file called mange s and it contains a lot of random stuff that's not random I hate when people misuse the word random even though I just did that it's not at all random it's very important web pack magic at the top and then you can see buried in there is our code now it's actually wrapped in some some braces and parens and curly braces that's because web pack isn't just adding our code as just I don't know regular code to the end of the file it's not just appending it down here it's wrapping it with some webpack magic and in the next video we'll actually take a look at it and understand what it's well try and understand what it's doing but for now it's good enough to see that our code is in here so it has nothing to do with the rest of our app it has nothing to do with these component services with the logic of that little calculator it's not even loading right now so let's fix that let's go into our index.html and at the very end include another script this one instead of app slash a pas it's going to be dot slash dist slash main dot J s this is the file web pack spit out for us this is what I just built it's very simple it took one file in I had a single line and it spit it out with a whole bunch of other lines but that's all the web pack magic I was talking about we'll come back to it later so now if I go back refresh we're getting this hello from web pack that alert is working so seems the reason that if we put other code in here it would work and that's just what we're going to do we're going to put our code from the app in this file that's actually coming up next because it's not as simple as just you know copying and pasting it because we want to keep it across the different files so we're going to use es6 import and export to do that for us and then web pack we'll build this one file but the other thing we're going to do in the next video is configure web pack set up a basic configuration file right now it's looking for index J s and it's spitting out the code in dist main j s we didn't tell it to do that so it's it's rampaging on its own we're gonna try and rein it in and tell it exactly how we want it to work the last thing I should mention I'm going to add the dist directory into my kit ignore because just like node modules both of these directories don't need to be included when I push this up to github they just take up space and you can derive both of them from the code you run npm install you get node modules if you run NPM start web pack will build the dist directory with the main J s so I'm not going to include it with git alright so we're now at the end of the third commit if you're following along the next commit that we'll do in the next video has to do with webpack all about our app code and configuring it so right now our app is existing in a vacuum webpack doesn't know about it we have web pack up and running but it's only bundling this code right here what we want to do instead is call some code in here that is from our application and we have these five different application files inputs are valid parts and foot's and so on and we're going to call some code from this file so when I bundle this file with NPM start it's gonna go grab all the relevant dependencies and put them all into a file which ideally is going to put all of these five files together for us but first we have to declare which files depend on what and the way we do that is by using es6 imports and exports so in each file we're going to indicate what will be exported from this file as well as making sure to import any relevant dependencies for example if we look at this one alert service it depends on inputs are valid so we're going to make that clear we're going to import inputs are valid but we actually can't do that yet because we haven't exported anything from that file so if we look at that here it is just a single function I'm going to export inputs are valid and then inside of my alert service I can now import it imports and I didn't export defaults so I need to use the exact name here instead of curly braces inputs are valid from and then the path to that file from alert service is dot slash utils slash inputs are valid and then while I'm here I might as well export alert service because we're using that instead of our app j s you can see right here I will need to import alert service but let me just begin by exporting the other thing so we've got component service it doesn't have any dependencies in here as far as I can tell we have inputs are valid we're done with that we exported it we have what's the other one parse inputs we will export that and where are we using parts inputs I think it's in app you can see right here we rely on parts inputs and inputs are valid so I'm going to copy this line from Alert service and move this into FJ to the top and we also rely on parse inputs from dot slash utils slash parse inputs okay and then we have alert service and component service that we're using in here but I'm going to hold off on doing that for just a moment because we have to talk about what is going in our index J s right this is our entry point this is where webpack is going to start we need to run some code from here that will then send webpack sniffing down through all the files to figure out the dependencies to figure out what code needs to be bundled so we need to have a little window into our application code and the most logical choice would be to run this function to call this function from inside of index this is the function that starts everything so instead of calling it inside of our app J s I'm going to delete that so I export it out of this file so now inside of my index J s I can import run from and then the path to that file from index J s is dot slash o not in the right spot dot slash app slash app is the name of the file and then I can call run but that's not the end of the story because if we look at what run is using we need to pass in an instance of the alert service and an instance of the component service so I'm going to cut that out and move it over to index J s but that's not enough I can pass in a large service and I can pass in component service but we still have to import them here just like in every other file where we're using something this is a bad example component service another bad example let's look at alert service we need to import inputs are valid because we're using it in this file same thing here if we're trying to instantiate a new alert service we need to make sure make it very clear we need it this is going to tell webpack all right we need to make sure alert service has loaded before we can actually create one and pass it into run so import alert service from dot slash what are we we're inside of index J yes so app slash alert dot service and then I'll duplicate this and this other one is component service from app slash compose servus okay now we should be okay we'll double-check we're importing everything we need so importing run alert service and component service then were calling run with the new instances of alert service a component service app j/s now just has this run function but it also relies on inputs are valid and parse inputs as you can see we're using it in here inputs are valid parse inputs they have no imports they only export a single function and then we have component service it doesn't import anything but it does export and lastly alert service we export it and it relies on inputs or valid okay so let's see what happens now when we actually run NPM start we now have code we have an entry point into our application it's not just an alert and webpack is going to go and I keep saying sniff I don't know why I have that idea in my head but it's gonna burrow down and and start looking in here and look at what app depends on for run and it's gonna realize this depends on inputs are valid and parse inputs and then it's gonna check those do they have any imports do they export something and it's gonna keep going and essentially form a tree for us so let's see what happens when I run NPM start hopefully I don't have any typos okay now let's look at what it built for us in the disk directory mange is now we can see all of our code is down here shortly well address what all this is but all of our code is here it's not just a single alert anymore and we have our script included as you can see this slash mange is the true test will be if we can remove all of these scripts that were there before and just have this one main.js file and have everything work still so let's see I'm going to refresh the page it looks like it's working okay looks good and if we go to our sources tab what we can see instead of our dist there's a mange a s it's minified it's hard to read and understand we will talk about that but it's working all of our code is loading it's being bundled into a single file so it doesn't matter you know which order we're writing these files in we don't have to indicate you know this file must load first and this one must load second we just indicate this file depends on this and this and then webpack takes care of the rest it makes sure that everything is loaded in a valid order okay so I just committed the code again if you're following along everything I just did is in the fourth commit just show you the git log so far right here web pack now bundling all our code that's what we just set up so we still haven't configured web pack to do anything beyond the default configuration that's coming up next but it's at least running all of our code it's bundling it all together making sure everything is in the correct order or making sure that the dependencies are managed nicely and then we include a single script tag and all of our code works so this would apply instead of four files where we have 40 lines of code the same idea applies where we have 100 files with 50 or 100 lines each as long as we write explicitly what each file depends on and what it exports ok next we're going to configure web pack we got to set up our own configuration file and we'll dive into what's actually happening in this main J's file I'm now working on the fifth commit in our application if you're following along with git and what we're gonna do in this video is configure web pack or at least set up the config file and replicate what it's already doing but we're gonna add a couple of other settings to change the output so we're gonna begin by just talking about what it's doing for us right now so we've already seen this the default place it's looking for an entry point is index j SN stead of source I didn't tell it to do that the only thing I told it to do is just run web pack when I run NPM start it just says all right web pack do your thing web pack says oh there's no config I'm gonna look for index J s instead of source we didn't have it there a couple videos ago and it gave us an error and the other thing it's doing is it's putting the code in a directory called dist in a main J's file I didn't say it should do that either that's the default behavior so if we want to change that or in our case if we want to add on other things like we're going to talk about plugins and loaders throughout the rest of the course we have to have a config file to do that eventually we'll actually have one config file for development one for production but I'm just going to make a file I can call this whatever I want I'm gonna call it webpack config is and then there's a couple of weird things that we have to get out of the way the syntax for these files looks like this so we're going to export an object and it's going to have a couple of properties we're going to add an entry point which I'll leave as an empty string for now we're going to have an output which will be an object and we'll start with these two so our entry point if we're just recreating what we already have its dot slash source slash index J s so not doing anything new for us but we're explicitly telling it to do this now because it will allow us to in addition add some other functionality down here which we don't have right now now where do we want it to output it well the first thing that we can configure is the file name not fill name file name if we wanted we can keep it as maing is we could go with I don't know hello J s just to show you that it works and then the trickiest part is we have to tell it where to go where to actually spit that code out and to do it we're going to import a module from node that we get we don't have to install this it's just comes with node it's called path Const path equals require path and what we do is write path dot resolve double underscore Deere name directory name and then the name of the folder that we want the code to go in so in my case I'll do dist but to show you you may not want to type this because you're going to make an extra directory but just to prove my point I'll just call this code like that oh and I'm missing my equal sign up here okay no wonder my editor was yelling at me so we have file name hello J s path is path dot resolved so what is this all doing what is path dot resolved well what this is going to do is resolve an absolute path to this code directory so it's going to take whatever the current directory is so if I'm running this on my machine this path will be something like slash Colts or I think I'm actually using a different account called recording user slash document slash wherever all my stuff is slash code but then if someone else is running it on their machine we don't want to put this recording user hard-coded hard-coded in there as the path for the output so we can use passed-out resolve which will take the current directory name dear name which every node script has automatically loaded by default anyway this is just a long way of saying we want to make a file called hello J s inside of a file or a directory called code so the last step if we want to use this configuration is to tell web pack to use it so right here in our package JSON we can pass it pass in - - config and then the name of the file web pack dot config dot J yes okay so I mentioned you may not want to actually run this if you don't have this set up as dist and main j s because it's gonna make you a new folder and a new file and I'm just going to delete mine right after but let me show you that it works fingers crossed that it does work let's see what happens all right we have a new folder and file called hello J yes so that is coming from web pack it's not doing anything with dist anymore we could delete that but instead I'm gonna delete my code directory so let's do that now RM dash RF code ok that file is gone I'm going to change this back to main J s and change this to be dist and that's what most people will do or you could have the folder called V call build instead but there's a lot of options but code is probably not the best example so the next thing we can do just to show you why you would even do this if we're just recreating what we already had why go through this effort well we're gonna spend a lot of time heading in different plugins and loaders and having web pack handle different types of files but for now remember how I said all of this is minified and ugly and hard to understand what's happening is that it's running in production mode by default and I can tell it let's not do production let's set mode to be development and that mode is going to tell it to stop minifying so now if I rerun my code or if I rerun web pack inside of dist we have a mange is and it's no longer all scrunched up into this really hard to read thing of now usually you're not gonna read this anyway that's not the point you read your code in the files where you're writing it but then webpack spits out a bundle but just to show you what it looks like you can see all of it here now one thing that's kind of annoying I don't know if you can see this it's using eval all over the place this is another thing that it's being configured by webpack automatically if we want to change that it's not really a performance issue but just for understanding what's going on we can add another thing called dev tool and if we set dev tool to none and I always forget it's a lowercase T if I rerun it this time again this is not something you need to do but if I look at the code now you can see that all of our code is in here relatively unchanged we don't have that weird eval stuff going on so this allows us to actually understand what this file is doing so the very top of it is some webpack stuff that has to do with defining different functions to make a web pack module there's one called web pack require so if we look at the code that's added in further down for example if we look at alert service let's look at the file alert service has this class as we've seen in an exports that class but it also imports inputs are valid but let's look at what web pack put in the file if we go to our now I guess I closed it our mange is we can see that it says exports provided alert service and it wraps the entire thing in this function to create a web pack module all of this right here it ends right there but then inside of it we don't actually have our import anymore I don't see that line that we had at the top of alert service that said import inputs are valid this is gone and it's been replaced instead with some web pack magic where we have web pack require see right here web pack require source app utils inputs are valid so web pack is now taking control and this web pack require is making sure that our code is all loaded in the correct order it's managing what depends on what so it's basically using this as a hook seeing this here and realizing and what's not realizing something but it has logic that is making sure that it's doing its own webpack version of requiring that module so if we keep scrolling down we can see you know for other things like app J s FJ s depends on parse inputs so it's requiring it with webpack require and inputs are valid webpack require and we can keep going and you'll see that all of our code is in here it's been added in and slightly modified to use webpack require to be wrapped inside of a webpack module and a lot of that or all of that logic is coming from here okay so I'm gonna go and undo or delete the dev tool none we'll come back to that later we'll talk about source Maps but I'm going to leave mode at development for now so we're gonna end here actually we haven't really configured very much we've just seen how to recreate what we were getting already although we did add in mode development but in the next video that's all going to change because we're gonna start talking about loaders how do we handle different types of files that aren't just JavaScript so that's coming up next we're gonna have to edit our config file so I'm going to commit right now if you want to just see this code it is the fifth commit so we've seen how to take different JavaScript files and bundle them together with web pack it's pretty simple it's the default behavior of web pack we just tell it here's where you should start now just go grab all of the code that's it's somehow related to this index file so go grab run and then it's dependencies and so on but that's just JavaScript but we started out a couple of videos ago talking about how web pack can bundle all sorts of files images and other static files things like JSON sass CSS SVG's there's a ton of stuff we can do in this video I'm going to show you how we actually do that we have to install some packages we have to modify our web pack config and we have to talk about loaders so loaders are the magic or the key for getting web pack to handle different types of files besides JavaScript so they are different packages that we install and they dictate how certain files should be pre processed as you import them or as they are loaded so you can transform files and do different things based off of the type of file or exam we can handle a CSS file one way and we can handle a SVG file another way so on the web pack documentation there's a list of some of the most popular loaders you can see under styling where it's that there's quite a few we'll talk about what the difference is it seems like style loader would work for CSS but then there's CSS loader what do they do how are they different we'll also talk about getting sass to work towards the end of this video as well and then this is not just a complete list there is another link that will take you to a different web page that shows you a whole bunch of other loaders that other people have written so my point is that loaders are really really useful it's how we get web pack to handle to pre-process different types of files so we're gonna add some CSS into our application we're gonna start really simple I'm on commit 5 working towards commit 6 if you're following along so I'm gonna make instead of my source directory a new file called main CSS so remember a couple videos ago when I showed you the large create react app that had 30 or 20 different CSS files and they're bundled together we could have web pack do that for us but we're gonna start simple with a single selector we're gonna set the body background color to be purple for now so of course right now we're not going to see anything because we're not including this in our HTML file we could include it as a script manually but the idea is to go through web pack we could have 20 something files of CSS web pack should undal them together and then somehow get it to just work the somehow part is what we'll talk about so we're going to need to use two different loaders one is called style loader one is called CSS loader so we can begin if we come down to styling we're going to begin with CSS loader and before we go any further we have to talk about how we actually set up these loaders this is what we add into our web pack config file so under module which is an object we're going to pass in rules which is an array and we can put different rules for different types of files for different modules so we can say in this case if a file ends with dot CSS if the name of the file this is a regular expression if you're not super familiar with regex this dollar sign means that it has to end with dot CSS so it can't have CSS just in the middle of a file name there has to be a period we have to escape it so that's the backslash period CSS end of string or end of name and then if that's the case we will use these two loaders so we're going to begin by installing both of them and I'll tell you what the difference is and why you need both in just a moment but let's do our npm install - - save dev style loader and CSS loader okay while that's going I'm gonna go back into my web pack config and I'm going to update this to now have module and then we have rules which is an array and then we're just going to add our first rule where we add tests and remember this is a regular expression and obviously we can just copy this one for now just like this okay and this says the file ends with CSS if that's the case how do we want to handle it and then we can pass in use which is an array and I'm gonna start with just CSS loader okay and I don't know why I have this extra G down there so we're saying anytime you come across a CSS file use CSS loader which hopefully installed it did now we have to make sure our app knows about our web pack knows about this main dot CSS file so we're going to add it we're going to import into our index J s so import and we need main CSS so dot slash main dot CSS so if I do this now web pack will come across that CSS file and it should match this regular expression and it will use a CSS loader so let's see what that does NPM start okay let's go look at our main J's file we're gonna have to do some scrolling I'm going to search for purple and you can see down at the very bottom we have our main CSS and it's showing up in this JavaScript file so what's happening is that the CSS loader it exists to take CSS and turn it into valid JavaScript code basically turn it into really long strings and make sure it's valid JavaScript you can see our selector here body background purple but it's not being applied right now at all if I open up this page if i refresh right here there's no purple background even though that code is included so that's where style loader comes in so CSS loader takes your CSS and it turns it into JavaScript and then style loader will take that JavaScript which is actually CSS and inject it into the Dom you can see right here style loader adds CSS to the Dom by injecting a style tag okay so to use it it's really simple we already installed it we go to our web pet config the trickiest part is that you have to know that there is an order to this array so we have to use them in the correct order this one is going to translate CSS to JavaScript and then style loader takes that JavaScript and injects it into the Dom so we need to make sure that this happens first we have to translate the JavaScript before we can inject so you might think we would put style loader second they actually load in reverse order so we need to put style loader here and then CSS loader so when it encounters a CSS file it's going to start with CSS loader translate it to JavaScript and then injected via style loader so let's see if it works now I'm going to build NPM start let's go back check our mange is do a search for purple okay it's still here but now if we refresh the page it's now purple so how is that working if we look at our index.html as we've already seen there is no link tag as far as our purple body we only have this bootstrap CDN but there's nothing that has to do with our CSS that we wrote the way that it's actually getting added here is through that style loader it's being injected if we look in the elements tab in the head you can see that there has been some style added we didn't do that web pack did it for us so that is our first little taste of loaders I know it's confusing because we're loading CSS without ever actually connecting it to a link tag in a HTML file it's all happening through JavaScript so if I wrote more code in main dub CSS or if I had a bunch of other CSS files and they were all connected each one would be parsed and turned into JavaScript and then injected into the Dom now later in this course we'll see how we can actually spit out a separate CSS file so if you wanted to have in your your dist folder you wanted to have main dot CSS there are ways to do that and we can minify it we can do different things to the code but for now we've set up our first loader so I'm going to commit right now because I'm actually going to change things to show you how we could set this up to work with cess s CSS files so first I'm going to commit I'll be right back okay so we're now moving on to the next commit what we're going to incorporate sass so if you're not really familiar with sass it allows us to write what is it syntactically awesome style sheets it's the original what it stands for si SS but now most people use as CSS files it doesn't really matter but what we're going to do is write some nice sass that will override the default bootstrap colors like for this button right here we're never making that blue it's coming from bootstrap to override it we need to use sass so the first thing I'm going to do is actually install bootstrap locally so npm install' - - save dev bootstrap so that's just going to get me the copy of bootstrap on my machine and then I'm going to begin by in my index.html removing this entirely so we have no bootstrap right now we're not including it if i refresh we just get our purple color from that main CSS so now what I'm going to do is change my main dot CSS a bit and then delete this and I'm going to rename it to dot s CSS now we could have actually kept CSS and sass and I thought about doing that to show you two separate rules but it would be kind of weird to have CSS and sass at the same time because if you're already working with sass most people would just prefer to write sass because it's a lot it's easier it gives you some nice features that you don't have in regular CSS so if you want to see how the CSS works on its own like we did earlier you can just go back to this commit but I'm about to change things to use sass okay so in here what I'm going to do now is actually import bootstrap which is from this node modules to readjust installed it and the import looks like this at import bootstrap /s CSS slash bootstrap ok so right now we're not overriding anything we're just trying to get bootstrap to work again but using sass this time so if you don't know how sass works it's not valid CSS on its own it has to be compiled or turned into CSS so I can't just do this I can't say ok when you find an S CSS file any file that ends and dot s CSS use style loader and CSS loader because it's not CSS so this is going to cause a problem but what we do is use another loader if we go back to loaders here under style go back a page there is a SAS loader if we use less there's a less loader stylist if you like stylus and so what these will do is take in this case takes s and turn it into regular CSS and then we take that CSS turn it into JavaScript then take that JavaScript and inject it into the Dom so a three step process now notice that they they mentioned it it does rely on another package called node sass so we're just going to install all of them together sass loader and node sass so let's do that now npm install - - save dev sass loader and then it depends on node sass and while that's going I'm going to update my config file to say s CSS I've already done that and we need to make sure that it's now using sass loader remember the order matters this happens first I'm gonna add some comments here actually to make this a little easier to understand so this happens first I'll do one turns s CSS or sass into CSS and then this step two turns CSS into commonjs so it converts it to JavaScript which is what we see in our file here for example here is CSS but it's actually valid JavaScript code then the last step which is step three inject styles into dom okay so those are the three steps and we should be good to go assuming my install worked let's see what happens so I'll save and I need to update one thing forgot we're importing main dot CSS here that doesn't exist anymore now it is a s CSS file a sass file let's see what happens when I run NPM start moment of truth okay we go to our main show yes and we should see a whole bunch of stuff now this is all the bootstrap code that we imported it's turned from sass into CSS from CSS and some JavaScript which is what we see here and then it's injected into the Dom if we refresh hey we're back to our nice bootstrap now we haven't actually overridden anything so we're gonna do that next it's really easy now we have all the sass setup we can write sass wherever we want as long as it's an S CSS file and we're importing it somewhere I now can override the primary color so this is a primary button so the way we do that is by writing not capitalized dollar sign primary and then giving it a color like teal for now so if we'll save and we rebuild over here go back refresh the page you can see that the default primary color is no longer there we're getting our own color and likewise this error color right here is I believe danger is the name of that color so if I want to change it I would say at danger what am i doing at dollar sign danger is now going to be let's just make it purple just to see what happens I have to build again soon we'll get a dev server setup so I don't have to keep doing this anytime I change something webpack will know about it and it will reap undal for me and there we go we're getting purple now so we are successfully loading sass through web pack it's such a it's sort of a convoluted crazy idea but it's really nice we only have one file but we are including this bootstrap file too but imagine we had 20 different files they all get combined together they start a sass they turn into just CSS then CSS the JavaScript then JavaScript inject it into the DOM and remember there is no CSS file in our sources it's all just index.html and mange is mange s is adding the CSS in into the head right here and you can see all of those styles is really long because of bootstrap so we will see how to get it to spit out a standalone CSS file but we're not there yet so I'm going to commit again we're done with this little section we saw our first couple of loaders these allow us to have webpack pre process certain files in different ways we write a regular expression we install the loaders we say which order they should run in and we just let it do its thing that's what loaders are there for alright moving on I'm going to commit I'll see you in the next video so next we're going to talk about a really important feature of web pack which is called cache busting it's how we can prevent certain assets like our main bundle J s or our CSS bundle once we once we actually make a separate CSS bundle whatever those files are how we can prevent browsers from cashing them when we don't want them to be cached so I'm going to begin with a really quick overview of caching so I'm on just a web pack repo on github if I go to my network tab and I do a hard refresh hard refresh command shift are on a Mac you'll see I'm just looking at CSS only there are two CSS files and notice their names they are quite long and ridiculous in addition to that we have over here let's see under size you can see the size of the file now I'm going to do another refresh but a regular refresh not a hard one so these assets some of them might be cached so I'm gonna refresh without shift so no shift key notice that this time it says from disk cache so what this means is that it's using the copy that it already had my browser remembered this file it remembered this file name and it decided okay we already have that we're not going to go get the new copy because nothing has changed or we assume nothing has changed it's the same name and that's pretty simplified explanation but this can cause problems if right now we're using what mange is if every time we write code and we bundle it it's always called mange is then it could be cached and someone's browser and we could completely overhaul the application code and we build it again we push it up to our server it's running and that person request our website there browser might say oh I already have mange a s and just use that version so what we can do instead is add in this crazy jumble of numbers and letters which is called a content hash into the file name and what's special about that content hash is that it is actually determined it's based off of the content in the file itself so if nothing changes in that file we will end up let's just do a simplified version ABC so right now my code and mange s all of this code we run it through this special hashing function which is I believe it uses one called an md5 a relatively or very famous hashing function and we get ABC so next time we build nothing has changed we still get ABC but then I change one character or I delete everything and rewrite all my code I get a completely different hash so that time it might be this instead now they're much longer they're much more complicated but that's the idea so every time we change our code we get a new file name but if we don't change the code the file name stays the same so that caching still works but we're busting cache busting when we change something in the code we get a new file name so right now it's main dot j s every time that's a problem all we have to do is add in content hash like this inside of brackets and usually you want to do main dot content hash or vendor dot you don't want to just do content hash J yes and you'll see that's what they do on github if we go back to network refresh one more time github - blah blah blah dot CSS frameworks - so they use a - but it's the same idea so we're going to implement that now with content hash and if I build right now it's going to take the contents of this file after it builds it and before it creates the new file but take all this code it hashes it using like I said I think it's md5 and it gets this special hash that only corresponds to the content in here and then it sticks that in the file name so let's see if it works NPM start we end up with content hash what file doesn't make for us take a look main dot 1 e da 8f blah-blah-blah-blah-blah and if I run it again without changing anything it should be the same still and it is one ETA so remember that one EDA now I'm going to change something in my code I'm going to add a console dot log to my index J s console dot log hi so now the code when we build main j s will be different and that means that the content hash will be different which means the name is different so now we have fa20 b15 blah blah blah so we are getting these new file names anytime we change the code but if we're not changing it it stays the same so this is really useful because if you have like we felt later on we'll have a vendor J S which will contain libraries things that aren't going to change as much those won't need to change they stay the same so we can just catch them or the browser can cache them but our application code might change more often so then we get a new file name each time which then when it's requested from the browser it won't be cached or it won't use a cached version because it's a new file name it hasn't seen before so that's all great but we have a problem how are we going to link how do we include that script or index.html right now is including mange is how are we going to dynamically predict or what are we going to do we can't just assume that it's going to be this every time because it changes so the answer is we don't write the script ourselves we don't include this script anymore we're gonna have web pack build our HTML file for us and stick it in this folder so it's going to automatically come up with the correct script name and put it at the bottom but to do that we have to learn about plugins so let's do it alright so plugins according to the docs give us the option to customize the web pack build process in a variety of ways very useful definition here so web pack comes with a bunch of these different plugins that they talk about on their web page but there's also a whole bunch of third-party plugins that you can find here awesome web pack contains I don't know a couple hundred of them so they do all sorts of things we'll see a few more throughout the course we'll find one we'll use one that it's going to help us minify our CSS and export CSS files we'll see one right now which is the HTML where are you HTML web pack plug-in which will help create our HTML file for us and we'll also see one that helps us clean up our dist folder because spoiler you might you might notice right now it's getting clogged every time we run start NPM start we're getting some times we're getting new files if we changed our code we get a whole new file and if we use this clean web pack plug-in it will help clean it up so plugins give us additional functionality so let's talk about the HTML web pack plug-in it simplifies creation of HTML files this is especially useful for bundles that include a hash in the file name which changes every compilation that sounds like exactly what we need you can either let the plug-in generate a file for you or supply your own template so we'll do both we're going to begin by just having it make a file for us the first thing we have to do is install it NPM install - - save dev HTML web pack plugin so I'm just going to copy that one move it over here and paste it while that's going let's look at how we use it so we require it in our config file and then there's something new we haven't seen yet plugins this is something it's a property we add to the object that we're exporting just like entry or output and plugins we pass in an array that contains as many plugins as we want so let's try it out so let's make sure we are requiring it in our web pack config at the top and then we can add in plugins which is an array don't forget your comma I always do that and then I get an error when I try and build and then we'll just pass in new HTML web pack plugin so we're making a new instance of it and for going safe so we haven't configured anything let's see what happens I haven't told it what name I want the file to be I haven't told it what should go in that file all I've said is use this HTML web pack plug-in which is going to make me some file let's see let's run npm start hopefully no errors okay let's go back and look at our distal dur something changed index.html it's very simple very sparse it has a default title I didn't tell it to call it web pack app I didn't say it should be indexed either we can change that if you wanted to but I like index it's logical and most importantly our script is included automatically at the bottom so whatever this content hash is every time if I change it if I change those files we'll end up with a new script now we have another problem which is our content is not in here so even though my JavaScript is included if I open this file right now which for the record is not the same file I've been opening I've been using this index where I hard-coded in main j/s but that's changed now that doesn't exist or mange is is not being exported anymore so instead I need to use this index.html I need to open this file from my dist directory so I'll just do it from the terminal I'll do open dist slash index and we have a problem there's no content on the page our script is here as we saw or as I talked about so that part is working but what about our HTML content this is where we need to tell it a template to use so this line somewhere where is that you can either let the plug-in generate an HTML file for you supply your own template or use your own loader so we're going to do the most basic template possible we're not going to use a library we're not going to do like handlebars or any other templating language we're just going to do a plain HTML file so I'm going to come over wrong way here we go I'm going to make a new file inside of my source directory and I'll call this template dot HTML and I'm going to go to my original index copy the whole thing over into template HTML but I'm going to delete things for example we don't need this bootstrap anymore web pack is going to take care of that I don't need this script tag web pack takes care of that I'm going to leave this SVG file we're going to back to it in a second or a separate video to address how we how does web pack work with images but for now this is our template so we're going to tell this HTML plug-in we use this code from this file put the script tag at the bottom and make sure it's the correct script tag whatever the content hash is it needs to match so now all we have to do is in our web pack config here where we're using this plug-in we need to tell it to use that template and we just pass in an object and a property so template and our template file is called template is no dot HTML whoops and that is coming from let's make sure we have this correct so this is from the web pack config file we're inside of source so we need to do dot slash source slash template dot HTML okay so it's going to use this template template dot HTML take this code put it into a new file which is calling index dot HTML by default and it's going to make sure to include our script tag at the bottom using the correct name the correct file name depending on which bundle we just built let's see if it works NPM start fingers crossed let's look at index ok so here's all of our code all of the HTML we needed and down at the very bottom we have a script tag and it's using our bundle so every time we build now if we change our code we rebuild we get a new bundle we get a new index file with a new script tag let's try running it make sure we're using the dist slash index dot HTML the image is not working we'll come back to that but our JavaScript is now loading our HTML is here it looks good okay so we saw a lot in this section we talked about plugins in general this is not the last plug-in we'll see but we actually started by talking about content hashing and cache busting how do we set up web pack so that it uses that content hash it's really simple as we saw in the file name when it bundles and then that enables us to bust caches if we change something we get a new file name if we don't change it it's the same file name every time so the caching the cached version is just fine if we don't change it in addition this caused a problem because we need to dynamically link to this file name it's changing so that's what this plug-in does we give it a template and it uses that it builds a file for us and this is the file we are now using so every time that we run NPM start it makes this new file and we open this file instead of this one we can actually delete this one entirely I'm going to do that right now okay so I'm going to commit so if you want to follow along committing now and I'll see you back in the next video so far we have one web pack config that we're using every time we build and that works great but often we want to have some different functionality for development versus production but at the same time there's a lot of stuff that is in common between the two so in this video we're going to actually have three config files one that is in common that's shared between Devon production and then one for dev and one for production so we can add things in like a development server a live updating server that we can just run instead of building the whole disk directory and having to manually open it we can use a web pack dev server on the other end of things with production we might want to minify we might want to export our CSS into a separate file so we're gonna basically set up the the framework for us to do that in this video just to show you what we're aiming for this is that react app I showed you very early on if I run NPM start it's not actually building a new directory it's not making a dist or a build directory instead it's opening up a live server you can see localhost 3000 my app is working and if I change something it updates automatically now if we go back and I instead run npm run build this is going to use production mode for web pack and you'll see that we don't get a live server it takes longer things are being optimized and minimized and we end up with an exported directory it's not exported but we end up with a new directory called build once it finishes so if I do an LS you can see now there is a directory called build CD build and there's a couple of files no live server but things are compressed there minified and they're ready for production so we're going to go for the same sort of idea we're going to have npm start start up a dev server in our little mini app and then npm run build will actually run it in production and create the dist directory but first we are going to make a couple of config files so we have web web pack config i'm going to make another file called web pack dev is and one more which will be web pack let's do prod PR OD is and i'm gonna begin by just copying what we already have into both of them and then we can selectively delete things so for example in production we want mode to be production and entry point we can get rid of because we'll keep that in the common one which i'll rename this to be common web pack commonjs these names are up to us we're going to pass them in when we actually run web pack from our package.json script so web pack common I'm going to keep entry point I'm gonna get rid of mode I'm gonna get rid of output because in my dev version I don't want the content hash in my production version I do it's easier in dev to just not deal with the hashing just have you know main CAS it's not a big deal but we can at least set up some differences so you can see it's working so we can get rid of entry but we'll do mange is over here we'll do main content hash is in production what else we can get rid of the plugins for now from dev and from prod those will be the same but we'll keep it in common we can keep the s CSS loading eventually will be minifying our sass and our CSS in production and not in development so this will leave the common file but for now it can stay here so this is the stuff that we have in common between the two and then in dev I'm going to get rid of all of these rules here and just keep it like this mode development production same thing so we'll be updating this as we go but right now this isn't going to work well it could work but we're not going to merge them with common so if I want dev to also include the functionality from common production to include the same functionality from common I'm going to use a package called webpack merge so npm install' - - save dev web pack - merge and this allows us to very easily merge web pack config together so that finished and I'm going to start by exporting actually I don't need to do that it's already module about exports from web pack commonjs now I'm going to require it here so we'll call it common equals require and then the path is dot slash web pack common so that gives us the contents of this file of common and then I'm going to import merge Const Marg equals require web pack merge we just installed that web pack merge right there now what I can do is set module dot exports to be the function call of merge or I pass common in and then this object you need to make sure I add my closing / end on there and what this will do is say merge whatever is in common which is this with what we have here in this object okay and then I'm gonna just duplicate this same thing we don't need HTML web pack plug-in in this file we're not using it we're using it in the common file so I'm going to go to production delete that and then I'm just going to copy the same line here right here and then add my paren at the end alright so all we're doing is changing mode and the output dev vs. production looks good save both files now we need to tell web pack which ones to use so in package JSON when we run NPM start we're gonna make it config web pack dot dev a s and then when we run build we'll set it to be web pack dash dash config web pack dot prod is and keep our fingers crossed let's see if it works so let's start with hmm let's do dev first so NPM start NPM start moment of truth it looks like it worked let's look at our index the new index.html you can see that the script is just mange a s it's not main dot blah blah blah ABC f-f-f-f-f-f-f something like that je s and if we look at the script its mange is it is not minified because we set mode to development now instead if i run npm run build so not just npm built with npm run build that's going to call web pack with our production file with this config file and let's look at our index you can see if we now have the content hash and if we look at the right file one seven nine d right there it is minified ok so this is just the beginning of setting up development versus production and we have it set up but there's a lot more that we can do to differentiate this two so the first thing I'm going to do is set up a dev server a web pack dev server so that when I'm in development I don't have to keep building like this I don't have to do n p.m. start every time I want to see something and it's really easy to do NPM install - - save dev web pack dev server and this is actually not something we really have to add into our config file instead we're gonna go back to our package JSON which is where are you oh my guess I closed it down or I'm blinded okay here it is instead of web pack we're going to run web pack dev server and then at the end we can optionally pass in - - open it doesn't have to be at the end but somewhere a flag and what this will do is open up the window in our browser for us so let's see if it works when I run NPM start we should now end up with the dev server open and opening it there we go it opened up automatically for me I'm getting all my code here and if I go and make a change let's say I changed the color in my sass file instead of teal let's go to magenta and save you'll see it automatically rebuilds and my browser refreshes it updates and you can see that happened over here well it's gonna be kind of annoying to point out but you can see it rebuilt again and the certain things change to detect them essentially you'll see a bunch of scrolling text if you change something the other thing I want to make clear about this if I actually remove the dist folder so RM dash RF dist you don't have to do this but I'm going to delete it now if I run NPM start which is using the dev server here we go we see our code let's tweak it back again one more time let's go back to teal save it updates automatically we'll close out with ctrl C if I do LS if I do LS if I use LS there is no dist folder so it actually does everything in memory it doesn't actually make a folder for you when you run it with web pack dev server which is nice we don't have to keep you know deleting these files or making these files and overwriting them it's all in memory but then if I want to spit it out npm run build this will give me my production version where i can now you know open it up manually or start i'm gonna put it on a server somewhere and you know use this as an application so now i would need to open dist slash index and it's working well aside from the image which we haven't addressed yet but our javascript is here yeah everything looks good alright so that's the end of this video I'm going to commit right now if you're following along I'm adding a bunch of detailed notes to the commits by the way so if you ever get lost you're not sure which one I'm using there's the main commit message and then some bullet points below that explains you know what we did all right so I'm going to commit now and then I'll be back with another video in this video we're going to talk about two loaders for web pack file loader and HTML loader as well as a nice plugin called clean web pack plugin so we're going to start with the loaders right now we have this image that isn't really working well it's not working at all and actually the reason it's not working right now is because my path is incorrect originally we had our index.html file right here on this level and the file it the image is assets slash web pack SVG so the path was just dot slash assets slash web pack SVG and I copied this whole thing into my template but now my template is inside of the source directory so what I could do is just change it to be dot dot slash assets as you can see this should work if I rebuild one more time my index dot HTML in the dist folder is now linking to dot dot slash assets so this does technically work but this is really not a good way of doing things for a couple reasons one is that we are hard coding this path in and it relies on assets being in a sort of a sibling folder being in the same folder as dist the dist folder is supposed to just contained everything we need it's supposed to be you know the the build of our app it should have everything we need contained in this folder so the fact that our assets is on its own and we just happen to link to it correctly is not ideal so what we're going to do is set it up so that my assets are actually copied into this folder and we'll work on hashing them for cache busting so they'll have new names sort of like our bundles down here and the links are going to be dynamic the source and our image will be dynamic so there's a couple things we need to do the first thing I'm going to do is move my assets into source so source will have an assets directory will reference it in here webpack will then take those assets copy them over to dist into a new folder and then I'll link to them and it will be sort of magic ok so I just moved the assets folder and then the path now needs to change in my template so my template is in the same folder so it's dot slash assets slash web pack SVG ok so that works but then we're going to have the problem when I run npm run build and I open index it's looking for dot slash assets but there is no assets folder in dist so we're back to our same error or issue before so we're gonna do two things to loaders to help us and the first one is called HTML loader and I have the docs open for it here on github what it will do is replace well any time it encounters a source for an image it will require that image it will tell webpack hey here's a file that we're getting we need to load I need you to you know figure out what to do with it and then we'll have to tell web pack how to handle those files like had to do with a CSS file or an S CSS file but instead we'll tell it how to handle JPEGs and P and G's but we're going to start with the HTML loader so it's pretty straightforward npm install - - save dev HTML loader and while that's going in our web pack common because this is common across all of it we're going to add another rule or the test will be for dot HTML at the end of a file name and then we're going to use HTML loader just like that we don't really have to configure very much this is fine on its own so what happens is that we're using this template HTML it's being required essentially web pack is going to encounter this and because we have this new loader we just added in that says hey if it ends with HTML let me take charge of it use HTML loader so then that's going to come across this source and it's going to require this image in JavaScript and then web pack is going to freak out because it doesn't know what to do so I'm going to show you that right now if I do npm run build we're gonna get an error here we go so what happens is it comes across this SVG right here because it was imported and it says I don't know what to do module parse failed unexpected token you may need an appropriate loader to handle this file type and indeed we do so we're requiring any images in our template now they are being required imported into JavaScript but now web pack doesn't know how to handle them so this is where file loader comes in so this will help us actually load those SVG s or PNG s or JPEGs so we're going to begin by installing it so NPM install - - save dev file loader and while that's going we can add a new rule and this one the test is going to be a bit different I'm going to copy this but instead of dot HTML and instead of just hard coding dot SVG I'm going to give it a couple of options so SVG or PNG or let's see JPEG or gif for now or jiff however you pronounce it so in a regular expression this is or so any of we'll match as long as there's a period and then one of these choices and then a dollar sign which signifies the end of the line so it's dot SVG and nothing else dot PNG and nothing else and then instead of just doing use and then passing in file loader I'm going to actually use a different syntax here where use is an object and we tell it the name of the loader file loader and then we pass in some options and the reason I'm doing these options is that I can specify things like the name of each file will begin with something simple name dot txt so remember HTML loader is importing this asset and JavaScript web pack doesn't know what to do with it but now we have this loader and we're telling it you should make a copy of this move it over into the dist folder with this name so whatever the file name is dot the extension but I'm also going to add in the hash just to show you that we can do that and it's not as far as I know it's not content hash like it is up here or is that in production it's hash maybe both will work but this is what I've seen in the Docs and then I'm going to give it a output path and this is where our assets will go so I could call it images just to show you that we can do something different and now instead of our disk falter that close node modules down when we run this web pack is going to encounter this image because the HTML loader encounters it inside of our template because we used a source it imports it and this loader is triggered right here where we have SVG that's matching so then it copies it over into a new folder called images in our dist and the name is going to be web pack dot SVG with a hash in the middle okay let's see if it works so we're gonna run npm run build and it looks good so far instead of dist we have a new images folder notice the file name it's really long web pack dot content a SVG and the best part if everything works our index.html now has image with the source set to that it's no longer set to what it was before assets slash whatever SVG it is dynamically linking to the correct image so now if I added another image into the assets folder whatever I added in there if it was SVG or PNG or JPEG and then I used it in my HTML template a used image source equals something it would be required it would be loaded copied over with a new name there's other things we can do as well like setting a compression under images but I'm going to keep it simple so we are now loading the files correctly and if we go refresh the page we see the image and if we use our live server it also should work just fine and it does ok so now moving on to the plug-in I mentioned the clean web pack plug-in you might not notice this yet but if I go and make some changes to some of my code let's say I go back to index J s and I add another console dot log it doesn't matter what it is console belt lock J I meant to type hai but I mistyped if I build again NPM run build what happens is that we end up with another bundle and every time we build if the code changes we get a new j s file and we only use one of them our index only links to one of them each time so we'll quickly install a plug-in called clean web pack plugin which will delete the dist directory every time we build and then we'll have a clean slate to add our code into or for web pack to do it so to install the plug-in it's npm install - - save clean web pack or clean - web pack - plugin and while that's going let's go back to our web pack common although we actually only need to use this in production when we're using the dev server it doesn't matter because those files are in memory when we stop the server they go away in production it's actually exporting it's building the dist folder and making those files so I'm going to import clean web pack plug-in equals require and then it's just clean web pack plugin okay now I can pass in plugins here like we have over in commonjs where we're doing this HTML web pack plug-in can do the same thing but this time it's new clean web pack plug-in just like that so right now every time we build if we change our JavaScript or CSS or any of our code we end up with a new bundle file and that's just going to keep going until we delete them but now with clean web pack every time I run npm run build assuming I didn't have a typo we'll see that it is cleaned up and we only have one file so everything that was there is either it's deleted and rebuilt or if it's not being used if it was left over from the last build it's abandoned it's completely removed and again we only need that in production it wouldn't hurt to add it to common or to dev but in dev our files are using the dev server and they're just in memory temporarily they are not actually written down they're not saved to the system alright so we saw two things here file loader with HTML loader to get our assets into a new directory and have the links work correctly and then also we saw how to quickly add into production a clean web pack plug-in alright so I'm going to commit now and that's it for this video next up let's talk about configuring web pack to work to spit out multiple bundles instead of just one with everything we might want to separate out our own app code from our vendor code so let's say we're using the bootstrap JavaScript and a couple matanov jQuery and maybe some other library that we need but they're not going to change very much or ever in our application but our main code will so we can have two different bundles and one of them will be vendor dot content hash j/s it will stay the same almost all the time unless we update that code or or I don't know we upgrade which version of bootstrap JavaScript we're using or something like that and then we can have our main that changes more frequently so this is actually not too difficult to do all we do is set up a different entry point if we want so inside of source I'm gonna make a new file called vendor J s and to start I'm just gonna put I don't know alert hi from vendor just like that and then I'm gonna go into my web pack Commons is where we have our entry it's set to index J s I'm going to make it an object instead and then each property will be the name portion of a file main will be based off of index J s and then vendor will be based off of dot slash source slash vendor J s so now webpack is going to work its magic on both of these entry points it's going to take this first one and it will call it main but remember in production we have a problem in our output where we're always calling everything main so I'm going to refactor this to be named in brackets which will be main or vendor dot content hash and I'll also do dot bundle J s and then in dev I'm going to change this to be named dot bundle dot j s so that name is coming from here main or vendor we have two entry points let's see what happened to no need to add my comma all right let's try it with NPM start using the dev server it opens it up okay so we get high from vendor and then everything else loads okay that alert is kind of screwing things up but if we look in our sources we have a main bundle and a vendor bundle and our vendor bundle includes our alert as well as some other webpack stuff and our main bundle includes all of our files and everything that we have in our app logic the code that we're writing so let's go back and test it now in NPM run build and just make sure that the content hash is working so our file names are named correctly we have main content hash bundle bjs and vendor bundle jeaious and then instead of our index we now have two script tags as you can see so I didn't add either of those both of them are added automatically so you can see now hopefully you can see how this becomes pretty easy if you want to have multiple files or multiple bundles all you do is add a separate entry point so let's now go and add some bootstrap JavaScript in so you can see the utility of this so instead of my vendor J s I'm going to just import bootstrap just like that we already installed bootstrap up in node modules and we're using the CSS but we're not using here's the CSS by the way we're not using the JavaScript if I wanted to add a navbar in which requires JavaScript let's just use this simple one here which will use JavaScript when you collapse or when you shrink the page down it will collapse into the little hamburger menu so if we don't have JavaScript it won't work it's right now if I just comment that out I go to my template at the top of the body I'll just paste in my navbar save and now if I run NPM let's do just a local server NPM start we get the navbar and it does collapse but the toggle the drop down is not working we're not getting that drawer because javascript is not running from bootstrap so we go back to our code and vendor JSL import bootstrap and you can see we run into an issue so after I've saved over here and I imported bootstrap I didn't even have to restart the server but it says that bootstrap can't resolve jQuery which it relies on and popper j/s so two dependencies I'm going to install NPM install - - save dev jQuery and popper jeaious on the bootstrap Doc's it makes it pretty clear that you need those in order to use bootstrap I just didn't include them right away because we were only using the CSS which doesn't depend on those so now if I run NPM start and here we go as I collapse this down there we go our JavaScript is working lastly let's do NPM run build and we'll see our vendor j/s that has spit out right here has all of bootstrap JavaScript included it also has things like jQuery in here which is if I search for jQuery you can see there's what 71 instances of it here is where it's included we also have bootstrap we have popper J s so all of those dependencies are loaded and that's what our vendor J s file now contains and then we have our app code which is in main j s and it's all being minified - it includes the bootstrap CSS we will in the next video work on extracting CSS out into its own file but for now it's all happening inside of this file mange is okay so we just split up our code we imported bootstrap into vendor J s you could follow this pattern with whatever other libraries you're using so aside from bootstrap there's other JavaScript libraries that you want you can put them in vendor J s and they will be bundled together into their own file and it will always be that same content hash unless those libraries change or you somehow add something new in here or change the code this allows a browser to cache this file separately which is less likely to change and then your main file could change a lot more often all right so I'm going to commit my code with git and then in the next video I'll be back to talk about minimizing HTML and CSS extracting our CSS into a separate file right now we don't actually see a file here but it's just magically working so next we're going to talk about minifying CSS as well as HTML but first we're going to discuss extracting our CSS into its own file or files if we prefer so right now everything is being loaded through JavaScript here is all of our bootstrap CSS as a giant string in our main J's bundle which then is injected into the Dom as we've seen before as a style tag so this works there's no problem with it as far as functionality it's it's getting there our Styles show up but in production especially it's nice to have a separate CSS file rather than waiting for JavaScript to inject the styles and the main reason has to do with performance if I load this page I don't know if it's going to show up in the screencast because it's so quick if you watch it over here you'll see there's a flash of the unstyled content every time I reload the page or almost every time so what's happening is that the page loads there is no CSS at all all that is happening is a single or two JavaScript script tags at the bottom of the page so all of our content loads the HTML elements h1s inputs buttons then we get to this script and these two scripts run and one of them takes our CSS and it finally injects it into the Dom so it happens very quickly but everything is actually loading first so there is no stylesheet up here that is going to style things first so there is a flash of unstyled content there it is one more time so in production especially we want to avoid that it's it's just not a good experience for users we want our CSS to load have it be up in the head everything is styled and then our JavaScript can load and it might take a couple milliseconds or sometimes longer and we won't have to wait to get our Styles now the reason we're not going to do it in development mode is that it takes time to spit out CSS files it's much faster when you're just developing with the the dev server you don't want to wait each time that you save something or you change your code you don't want to wait for it to recompile and rebuttal and spit out new CSS files so we're just going to do it in production and the way we do it or one way to do it is using a plug-in called mini CSS extract plug-in so we're going to begin by installing it so it is NPM install - - save dev mini CSS extract plug-in and while that's loading we're going to go into our web pack production and import or require that module and then we can use it inside of our plugins so we'll pass it in we'll do new mini CSS extract plugin just like that and save and if we want we can specify a couple of options we'll just do file name and have file name be the same sort of pattern we've been following so name dot and then we can have the content hash dot CSS alright so that's the first step but this actually isn't enough the next thing we need to do is make sure we're using this instead of the style loader that we're using right here right now we're using this all the time it's in common webpack common so every time we load as CSS the same would apply if this was CSS we are first running it through sass loader and then CSS loader which remember this one converts sass to CSS this one turns CSS and the JavaScript this one is what actually injects those JavaScript strings of CSS into the Dom we don't want this to happen in production we're trying to avoid that instead we want to use this mini extract or mini CSS extract plug-in to grab those lines of CSS and put them in a new file so I'm going to actually move this this entire rule away from the common config file I'm gonna put it in dev because in dev we do want it and I need to grab module rules need to follow the same syntax that we had I copied the wrong portion okay so everything looks the same module rules and then in production we need to do the same thing so module rules but this time instead of style loader we're going to change this to be mini CSS extract plug-in dot loader so it comes with a loader that we can use as part of the plug-in and this instead of inject Styles into the Dom this is going to move or extract CSS into files so remember they load in or they run in reverse order this happens then this happens and then finally it should create new files for us including the CSS that was loaded by CSS loader that was originally converted from sass to CSS by sass loader oh right let's see what happens now we will do NPM run build fingers crossed no errors you never know and you can see it takes a little while but it should spit out a CSS file and indeed it does so we have this CSS file now that is separate and if we look at our index.html that it gives us it now includes a link tag up at the top so we're no longer waiting for the page to load for the JavaScript to load then inject our styles into the head it's all happening at the beginning it's compiled it's built this way from the get-go so that plug-in is extracting all of our code all of our CSS into one CSS file you can configure it to do it in multiple but for now one is fine this is all our CSS so bootstrap is pretty much all of it we override those colors using sass but if we had other styles as well if they would be in here assuming that we were writing in them in this file and now if we refresh the page let's make sure it still works notice we don't get that flash of content anymore I'm doing the same thing but it's not we're not seeing the unstyled content our link tag is included in the correct spot up in the header and I guess I should call attention I use the content hash again just to help with caching and to prevent caching when we don't want it to happen if we change the file this cache will change all right so that should be review from earlier videos so notice that this is not modified this is quite large so one thing we might want to do is minify this CSS and it's not very difficult to do there's a plug-in to help us and it happens to have a very long name in my opinion optimized CSS assets web pack plug-in one of the larger packages larger package names a large package oh boy one of the larger package names that I've come across so optimized CSS assets web pack plug-in is going to help us minify our CSS so the first thing we're going to do is install it so we'll do that now NPM install - - save dev optimized CSS assets web pack plug-in while that's going we're only going to minimize our CSS in production we don't need to do that in development it's a lot easier if we only do it in production it takes time but it's also you know frustrating if you're trying to debug something in CSS it's super minimized it's not a huge issue you can do it in development if you want but I'm just gonna do it in production so we first need to import it here I'm just going to use const to match everything else that i've been doing and where we actually use this it's not as a plugin on its own we add a new property here called optimize that we haven't seen before and then within that we specify minimizer and this is an array multiple minimizer's because sometimes we're minifying javascript or minifying CSS like we are in our case and I'm going to pass in new optimized CSS assets plug-in just like this and then add my comma okay before I run this to show you what happens let's take a look at two things I'm going to close down a lot of stuff we have a lot going on so inside of our build folder we have our CSS which is not minimized it's a very long file then inside of our JavaScript files we have minimized code so I'm showing this to you for a reason this is all minimized or minified now if i run npm run build where we're telling it to use optimized CSS assets plug-in to minify our CSS let's see what happens okay so that finished up and let's look at our CSS now it's minified so that part's working but something weird happened if we look at our JavaScript it's no longer minified why is that happening so it's kind of annoying that this happens but when you set mode to production by default optimization minimizer is set to use a javascript minify but then we're overriding it right here by telling it to use this off to my CSS assets plug-in it basically ignores what was there before which was minifying the javascript terse rjs plugin that will we're going to reintroduce in just a moment so we have to manually add it back in it was there but by adding in this plugin we completely override what was there originally inside of minimizer so now we don't get JavaScript being minified only CSS and another thing I'll show you if we look at the message we get it says warning an asset size limit the following assets exceed the recommended size limit 244 kilobytes first of all a lot of people think that this is a pretty sensitive or a low threshold for this warning 244 is not really a huge file but you can see our vendor j/s vendor bundle jeaious is quite large now and weren't getting this before because it was being minified it's not anymore so if we look at the file it's quite long it's all a bootstrap and jQuery and popper j/s so now we're going to add in the plugin that was already being used we don't actually have to install it but we do need to require it and it's called tercer webpack plugin again I haven't installed this myself it's already inside of node modules if you scroll down look for T cursor you'll see come on where are you right there tersh or web pack plugin I promise you I didn't install it myself it's not in my package JSON but it's there because web pack was using it already you can see it's not in here okay so we're going to require it and then pass it in as a minimizer new tercer plugin so tercer is the default minimizer for javascript and web pack as i already showed you it was being used before but we overrode it and ignored it so we're adding it back in it used to use webpack used to use Uggla fire by default I believe now it's tire but they do pretty much the same exact thing they minify your JavaScript so let's see what happens now let's try it npm run build again i'm only minifying in production for my javascript and doesn't work you can see how long this takes by the way so we don't get that warning anymore that's it's not saying that our file is too large vendor is now 167 kilobytes instead of what 400 something yeah 484 so a significant reduction in size and if we look at vendor it's minified if we look at our main file it's minified if we look at our CSS it's minified there's only one thing that is in index.html now it's very short but we can optionally minify our HTML in production we don't have to use any additional plugins we already have this HTML web pack plug-in right here I can pass in other options I can specify minify this is part of the the plug-in documentation where I found this and instead of minify I can do things like remove comments and set that to be true or false but I'm not going to do it here inside of webpack common because I don't want to minify my HTML in development so once again I'm gonna pull this out and move it to production so instead of our commonjs web pack config we don't have any plugins they don't share anything at least they don't share it in the exact same way so now inside of dev I'm going to add in this plug-in again so plugins and paste that in add my comma and I need to make sure I am requiring it at the top of web pack dev and then in web pack production I'm going to require it as well but I'm going to alter some options I'm going to pass in some minify options so let's do that now right here paste it in and after template I'm going to say minify and the three I'm going to go with our remove attribute quotes collapse whitespace remove any extra whitespace and remove comments set that to be true so let's let's do something in our HTML where we'll actually be able to detect this will tell if it's working so let's go to our template file and add some comments in here like mm how about above the navbar we'll say bootstrap navbar and then let's add in some white space I'll just do a single line and we'll just leave it like this for now we'll look for that top comment here bootstrap navbar and see if it makes it in to our end result when we are in production so let's now run NPM run build and twiddle our thumbs for a moment okay let's look at index.html all right definitely minified you can see the attribute quotes have been removed so type equals text there's no quotes for example we have no white space or most of the whitespace has been removed and then also my comment is gone at least I can't find it if I look for it I'm pretty sure we'd see it pretty pretty easily because it would stand out with a different color so it's not in here and let's just check that it does work so i refresh the page okay it's loading we're getting all the code that we expect scripts working its minified we're overriding bootstrap or using sass change those colors we have separate CSS files or single file where are you right here it's minified we have our minified vendor J s and our may NJ s and then our index.html minified as well so everything has been crunched down if we have our images to forget about that and then instead of elements we still can see everything that's normal right we're by minifying it we're not like corrupting it we're just shrinking it down and collapsing it into as little space as possible now let's just verify it still works in development so NPM start notice how much faster that loaded for me that took maybe a second or two to build originally and then rebuild should actually be faster and if we look at the code index is not minified we can see my comment is here all the attributes have quotes our code our javascript is not minified and there is no CSS remember it well it's in the files but there's no CSS file on its own and remember the reason we do that is that it takes a while to build those files and in development if I change something I don't want to wait and that's it for now so I'm going to commit we have a whole bunch of things going on in web pack and we've honestly only scratched the surface in some ways because there's a lot of other things to talk about I mean if we look at those that list I showed you early on if the different plugins available of the different loaders web pack can do a ton of stuff but as you've seen it's really how I put this intimidating it can be overwhelming when you're starting out and it's something that you only really do once every project maybe you go and update something but often you know you're not you're not writing code in this file and your web pack config all that often especially if you work at a company on one large production app the config file doesn't change all that much so a lot of people don't have much experience with it and it takes some time and some practice to get used to it but there's just nice little patterns you follow you know you just remember rules tests use there's certain loaders that you use frequently like style loader and tercer js4 minification you know there's these different patterns but at the end of the day all that we're doing is taking a bunch of different types of files in our case an SVG file an HTML file JavaScript files s CSS and we combine them in some ways not all into one file but we combine JavaScript into different files all of our different J's files you know we haven't touched these in a while but five different files plus the bootstrap j s+ jquery plus popper J s and we spit them out into bundles there minified they have hashes in their name that pertain to the content inside of them so those hashes will only change if the content changes which helps with caching and preventing caching when we don't want it then we have our CSS being pulled out in in production we have our index.html being built for us with all of the links included dynamically so we don't have to write any of these script tags right this is all done for us and then we set things up in development mode to be a little simpler we have our dev server that is going to update and rebuild anytime we change something just serving it on localhost we aren't minifying you know we aren't using the content hashes our CSS is not being extracted or hTML is not being minified but we're still joining together all these different files and making sure everything works for us okay so I'm gonna leave it off here I know that was a lot I'm gonna commit this will be the last commit for now please let me know if you have any feedback I'd love to hear what you have to think any suggestions or things you liked take a look at the code of course look through my commits and I think that's it all right talk to you later talk to you later all be on YouTube later if you enjoyed this video my cat and I really appreciate it if you share it with anyone you think would get something out of it I'll leave a comment subscribe please turn on notifications oh so annoying asking you to do that
Info
Channel: freeCodeCamp.org
Views: 204,834
Rating: 4.949419 out of 5
Keywords: webpack, webpack guide, webpack course, webpack tutorial, webpack example, webpack 4 example, webpack 4 setup, webpack setup, webpack 4 for beginners, webpack beginners, webpack 4 fundamentals, webpack 4 sass, webpack 4 scss, webpack 4 assets, webpack 4 dev server, webpack tutorial for beginners
Id: MpGLUVbqoYQ
Channel Id: undefined
Length: 113min 1sec (6781 seconds)
Published: Wed Jun 19 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.