Webpack 5 Full Project Setup

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome to swashbuckling with code i am jimmy cleveland and we are about to make a full webpack project now what do i mean when i say a full webpack project well let me briefly go over what we're going to cover so we'll be using webpack 5 and i'll show you some of its new features we'll be using babel transpiling for modern javascript and we'll be doing react with jsx production and development builds source maps hot module reloading css and outputting that css from a javascript import to an actual file sas post css with auto prefixing newer css features browsers list config for customizing cross browser support outputting images as separate files or inlined into our javascript bundle for faster loading of svgs or icons or any small images we'll be generating the output html file from a simple custom template and then we'll set up automatic cleaning of our output directory for a more realistic deployment setup then we'll quickly deploy and host our project on netlify with automatic production builds every time we push to the main branch and finally we'll add react fast refresh which is a really awesome new hot reloading tool that's maintained by the react team now a quick disclaimer this video is covering what i think is the most common type of webpack project which is like a single page app project and i won't be covering exporting packages though the end product of this will be extendable to a multi-page app or exporting your own packages or anything like that and as you can see there's a lot of content to cover in this video i've spent a lot of time on this trying to find the right balance between moving quickly enough to get through all the material in a reasonable amount of time but also explaining things as we go so i hope i did a good job of that but you can let me know if you have any constructive feedback like i said there's a lot of material to cover in this so i'm going to be moving through it fairly quickly but i will be explaining things as i go but if it's not in as quite as much detail as you would like i have other videos on this topic that delve into a specific areas that i go into a lot more detail of so check those in the description or in a notification that i'm going to put here one last note is that i'm not going to be going over routing for single page apps in this video that's because a lot of projects don't need or use it or when they do there's a lot of different preferences and flavors that people like and it adds a lot of complexity to it so i decided it was out of the scope of this video so now that you know what this video is going to cover let us begin let's start by creating our project so let's use makeder in my case and i'm going to make this webpack project i'm going to immediately cd into that project of course and then what i'm always going to do is i'm going to knit right away and i think it's a good habit to use git in general even if you don't want to host it somewhere just because you know you get that history it's easier to you know undo stuff and not worry about losing data and all that good stuff so then what i'm going to do next is i'm going to host it on github right away so i'll go over to my browser and this is my alternate account just for making these video repos nothing crazy and then i'm going to make a new repository i'm going to name this webpack config and i don't really want to do anything else but just create it and what you can actually do here this has always worked for me you might have to type these commands individually but you can just click this and copy it and then if you go back to your terminal and paste mine will prompt me just letting me know it's going to run some commands and because each of those line breaks will count as the enter key essentially it's going to run all of them and i just have to press the last one and there you go now we've all pushed up so if i reload here i guess i didn't really need to init there but you know whatever so then next thing we're going to want is we're going to install or we're going to actually let's do an init first npm y just to say yes to everything and then we might as well just install while we're here webpack webpack cli and webpack dev server is the first things we're going to need so then i'm going to open in code so right off what we're going to see here is uh git is saying that it has too many files to track okay and that's because we're tracking node modules and we don't want to do that so right away we might as well make a git ignore file and in there we'll type node modules and that you'll see this stop tracking it okay and then here this sometimes doesn't update for me recently i don't know why but you can just click refresh and then now we'll just be tracking the git ignore package.json etc so i'm going to go over to package.json and i'm going to clean this up a little bit i actually don't care about any of this stuff right here if i if i get rid of name version description main it actually says that a couple of these are required in the npm docs but that's mostly for packages and i haven't really had any problems with them i'm actually going to delete this as well i don't really care about hosting my repository since that's you know for a package keywords author license bugs home page don't need any of that now some people might think i'm crazy here but i don't really have any need for this type of stuff and if i do end up needing it as i go um then i'll find out and so i think it's a good way to learn is just to kind of you know trim everything you can and see what actually is there so you know just like sitting there kind of a bundle of anxiety of like i guess i need all these things and rant so i think we might as well just start off by adding some scripts here so the first script that i'm going to need is start and my start is going to be webpack serve this is the new way to do webpack dev server if you are familiar with the old one now i want to do a i want to do a watch because i always find this useful this is when i want to watch my files for save so they get updated but i don't want to necessarily serve it i might just be running it locally so i always do a webpack watch here and then finally most important to me is that we're going to need a build command and that's just simply webpack name these whatever you like of course if we come over here and do npm install i'm going to get a few warnings um you don't have to worry about this um fs events this is just a you know packages that are needed for mac that other operating systems can't use it's really annoying that we can't get rid of that these are the ones we're worried about though this webpack project no description no repository no license well that's because actually what we want is to set this to private and then set that to true and the reason is because this is not going to be a package and we don't want to accidentally publish this this is the whole purpose of this is to be you know a project website in the end and then if we come back over here and run install those warnings will go away we'll just be left with these ones that i try to look up and i don't think you can get rid of it so it is what it is and i think the logical place next is to create a new file here and we want to create it in a source index.js because that is the default place that webpack is going to look without any configuration so we'll create that and then i'm going to actually set up a little object for my demo i'm going to make an elven shield recipe oops and then for that i'm going to say leather strips that's two let's do iron ingot is one find moonstone it's 4. and then console.log there's nothing special about this it's just for example we're going to log it and then what we want to do is see if our npm run build command actually works it does we get a warning you don't need to worry about that it's just letting us know that it's going to default to production which means it's going to minify and mangle it and all that good stuff for the end user we will fix that in a moment but for now what i can actually do to make sure that it worked is i can go into dist and look for main.js and look there it is it runs and go back over to the editor here and you'll see that dist hassle has a main js and it's this one line format so that's where it's going to output it by default with no configuration pretty cool but we will want to ignore that folder now the reason that we want to ignore disk before we commit next is because this is going to be our kind of like clean slate output it should be repeatable every time and so when we actually host this on the server we we don't want to host all these files we don't want to pull them down from github already built we wanted to build them fresh every single time and so that is the reason that we're going to ignore the dist for now and i think it's time to commit so we've got our get ignore we've got package lock json i don't really ever look at that too much sometimes and then we just take glance over and say okay yeah this all makes sense the things we added and you know that perfect so i'm just going to say initial webpack setup and commit that and then you can just click this usually is that going to let me you can also do your standard terminal git push you know i'll be i'll be going back and forth so i usually commit pretty frequently i'm going to spare you all this time and i'm only going to commit during major sections but i think that it's a good habit to be in just to commit more frequently it's easier to roll back that's my two cents so let's actually make this a an actual web page here by creating a new file index.html and this is going to be blown out every time and we're going to deal with that later by that i mean you know every time we build uh on the server or somewhere else you know this isn't tracked so we're going to have to start over and index html is not going to be tracked so don't worry about that for now we're going to come in here i'm just going to use the good old emmit shorthand it's really nice and then here what we want to do let's actually make an h1 just so we can actually see it webpack we i don't care and then script we're going to do a source type and this is just going to point to main js okay so now we have our template and what we can do there's a couple ways we can do open this and look at it so we can right click for me and do reveal in explore however you want to go find that folder and open it up and then when it opens up here i can just click this little chrome and see it right here and if i inspect we should see our object printed out okay now if i go over to my terminal i should also be able to run my webpack dev server so that's going to start that up and you know it's all built and beautiful and then we just want to take this right here that's going to start our local server there and we can go take a look at that now what it's going to first do is it's going to show us just the whole directory is what it's pointing at if we click on dist that index html is the the root point for disk so it's going to open that automatically and that'll work the same okay if we open this up and install or go to console we'll just see this object but live or loading actually isn't working yet we need to have a webpack config to enable that so jumping back to our code let's make a webpack.config.js that's what webpack's going to look for automatically and from here is the standard you're going to do module.exports for node and then your i'm going to set the mode to development for now just so that we can actually look at the code and it's not all minified and harder to read and then the thing that we actually are here for is dev server so this dev server property whenever you're using a webpack dev server you can set this to content base and you just give it a relative path sorry to that folder where all your stuff is and then when we uh restart that server pm start we go back to our browser and this one shouldn't work because it's a subfolder here but we should go to oh that's interesting we should go to uh localhost 8080 and we'll be able to see that you can ignore this devtools thing for now that typically goes away but this liver loading is enabled now so let's see is that true well in order to test that out what i'm going to do is i'm going to add actually just to be clear notice that it's just logging out this one object that we've made so i'm going to go to our index.js and i'm going to make a new object this one's going to be a bit called elven gaunt let's recipe and we are going to use the spread syntax for the next part that i'm going to demo so we'll take this off of eleven shield we'll clone that and then i'm going to add like leather to it just raw leather so it's going to add this property and then i'm actually going to alter refined moonstone to be four there's four of those and then we'll just copy this and then i'll change this to elven gauntlets recipe so we'll log both of them now if i go back over here i should see this automatically logged out both of them so it reloaded and logged them both out so i could just manually reload and it'll do that cool right now we want to look at our output real quick this is kind of interesting if i go to my main.js it won't actually have any of that new stuff that's because webpack dev server is injecting that it's not actually building it into the disk folder just so you know and you don't get confused because i've been in that situation if i do npm run build now that we've set it to development come back and we'll see that it's output like this just temporarily to fix this it's a little bit harder to read here so what you can do is you can go to uh you can set dev tool to false we're gonna get rid of that in a moment but for now we'll do that i'm gonna rerun build come back over to our main js and uh you can see now that it's updated to look pretty normal and the output and you can see this spread syntax here and all that so that leads us to the next feature that we're going to want to add which is fable so we have this uh syntax is being straight up output but we actually want that to be transpiled um you know automatically to whatever uh you know babel goes and looks at can i use reports and what browser percentages have what support and determines that automatically and we'll customize it a little bit after that i have a video on this so i'm not going to delve into that too much it's the build a basic webpack video which i'll link and notification all that stuff but i covered that a little bit more there if you don't really know what babel's for but we need to cover a lot of material here so i'm going to move on so in order to add that let's go to our terminal we're going to add these are all going to be dev dependencies we're going to do babel loader since uh that's webpack's way of figuring out what what uh how to digest a certain syntax and then we're gonna do at babel core and add fable flash preset env so core so that we obviously have all the core functionality and preset env that's because those are going to be our like our standard defaults for you know last two browsers one percent usage or i don't know i don't know what their defaults are but somewhere around there now what we need to do to get this to work is first i think we should update our webpack config so if we just uh go to webpack config what we can do here is say we're going to now have a module property this module property is going to have a rules property this is pretty normal you get used to this it's the regular flow for setting up all your rules and then here you're going to do a test and this is going to be a regular expression test i think oh whoops we want an object here don't be silly jimmy so these rules are going to be series of objects you can think of it that way this first test is going to be a regular expression we're going to just look for js okay and we'll put the dollar sign there just to be a little more secure to say it ends in dot js any file that ends in dot js we want to run against that we're going to have to exclude uh node modules because babel transpilation is actually pretty expensive and we don't want to run it on a bunch of stuff that has no need to be run against for us so that will make it slower if we didn't do that and then use finally we want to say oh well how are you going to handle this well i want you to use this loader and it is babel loader oops so without any extra options babel loader is going to automatically look for one of the default naming conventions for a babel config file so let's make that now usually i do uh babel rc just because that's what i'm used to but in some cases you're going to want a config.js and that's what i recommend for this one so people.config.js is another one we can use and then i'll make it a javascript config so with that we'll need to do javascript module.exports as usual and then here this is going to have a presets array here and then we'll just use at fable preset enb that's our preset that we're going to use and that's it so now what we can do is if we do npm run build we should see going back to our main js we're going to have some extra stuff here that's interesting notice that the spread has been replaced by this object spread method and uh that's where it's defined so it's actually gone and made some a little bit backwards uh compatibility support for some of the browsers that don't quite have it yet still not as widely supported as we would like so now we know our babel's working now if we go back over to our terminal and start our server back up and go back to our browser here let's reload that real quick what i want to show is that if you were to look at any of this in the main.js you're going to see the final output code as you would expect okay it's all this the finally transpiled code and what you can actually do it's really easy and awesome is we can go back to our webpack config i'm going to wipe all these out for just a moment i'm going to go back to our webpack config and here we can change this dev tool false to source map all right now i should need to restart the server from that but i always like to check just in case someone's made some cool advancements it looks like it so let's go back shut down restart npm start go back to our server and then you'll notice now that warning has gone away finally but also notice that it's index.js line 14. let's go take a look at that and you'll notice that it's our pre-transpiled code it's our source code so it's that easy to set up source maps nowadays in webpack it's amazing i love it now at this point i don't want to keep switching back and forth constantly between whether we're development or production when we want to see the final build so what i'm going to do is go to my package.json and i'm going to say that my build command is going to set the node enb equal to production then what i can do in webpack is i'm going to say let mode equal development down here we'll set this to mode whatever we end up with and then we can do an if condition we can say we can check process dot env and we can say if that is if that node e and b sorry environment variable is equal to production then we want to set mode oops i'm not in an object we want to set mode equal to production pretty straightforward there now this might be a little bit weird to you i could have used a turn area there's a lot of other ways that we can make that cleaner but this will make a little bit more sense i think toward the end of the video i'm kind of setting it up in that direction so just bear with me on that when we start with this so by default we'll have development mode but if it happens to have this flag however you want to set it you can set it in an env file or in windows is a little bit different but either way you you set that environment variable to production you can just look that up how you can do that and it's pretty common now if we come in here we say npm run build we should see that our main js is all mangled and minified and beautiful so it's nice and compressed fantastic and then what i'm going to do is add one more script real quick i'm going to say i like to always have this around as a build dev script and then that will just simply run webpack without passing it just like our old one did and then let's try it out got to make sure it works build dev so that'll switch us between that so then i can just run this and you know when i actually want to see my normal output here but then on the server it'll run build i think this is a good point to commit our code and do a real quick review so we've got this babelconfig.js and that makes sense we know we added that package lock you know it's just our packages but what packages did we add well we added the script we added our babel core build preset env and babel loader just as a refresher here this is why i like to go through vs codes um diffing of the git uh i i just think that it's a it's a nice habit to get into to make sure that you didn't leave any accidental console.logs or any problems like that and to also kind of remember what you did so then uh don't worry about that i always get that uh webpack config we added the whole thing right yeah we needed all of this and then finally we added the spread cool so we'll say add fable to oops to project okay and next i think it's time to add some css support so let's start by adding our styles by having a styles folder as well as what i'm going to do it's not necessary i just like to do that and then here i'm going to do index.css we'll start with a basic css file now that css file is going to be pretty simple just we just want to see some results right so we'll say uh let's set margin to zero we could have done m0 there uh let's set our background color to i'm going to do peach puff today and then our color i'm just going to set that to two two globally now in our index.js we actually want to import this so we'll say import and we can just say dot slash styles slash index.css and then let's try to run it and see what happens so let's just try to just run build boom blows up right that's expected uh that's because you may need an appropriate loader to handle this file type of course so what we're going to do is install those we're going to do css loader and then we're going to use mini css extract plugin and you can use style loader as an alternative the real difference is that the style loader is going to inject it uh the styles into your javascript bundle whereas the mini css extract plugin is actually going to create resources or a final one single css file for that now which one do you use in which situation it kind of depends and sometimes i don't really know which is the best practice to be honest but at scale it seems a little more normal to just have the files because the request is a little linear than downloading this gigantic javascript bundle that has css put into it but sometimes you'll use style loader if you're doing like critical css so you might use them in combination uh you know you check for one uh all of your critical css at the top that's like you know your basic css and fonts and all that stuff and then everything that could be loaded you know below the fold to use an old term uh that can be loaded in with the uh minixtrac css plugin so let's set that up so here if we go into uh webpack config what we're going to do is need to import this and so the convention is just to call it mini css extract plugin and that's going to be equal to this should autocomplete for us so we've got that now and i'm just going to yank that name and then we'll go down to there's a couple spots here the first one i think it's a little quicker is we'll use plugins and in the plugins what you want to do is use the new command oops i hate when i do that i'm going to use a new command and you're going to call this constructor and then up here we're going to make an additional rule okay now this rule itself is going to be a looking for the css file so we're going to test against it just like before this will be case and sensitive we might as well we want to do a escape the dot cs that's all we need for now isn't it yeah we just need this for the first part and then what we're going to do is we're going to set up our loader again but what we can do is we can just set up this array chain here and say i want this mini css extract plugin dot loader that's the thing that we need off of that and then a css loader after it now in webpack everything reads kind of right to left and arrays so what's going to happen here is when it finds the css file it's going to use the css loader to process it and that's going to be piped into this which is going to spit it out into our disk folder let's see if that actually works so npm run build boom and in our dist we now have a main css file you can see that it's got the source mapping already built in because we just have that one source map setting to true so that's already done for us it's awesome now what we will need to do is link it into our html for now so i'll just do a link css can you not do that that's kind of we have to type that and then this is actually going to be main dot css and that should be it now what we can do is start our server and then check both of them so we'll start we will go to this one reload and we have our nice peach puff background perfect and then if we go back over to our webpack uh this is the one that's just from the file just to show that this is the built one and this is the served one and they're both working just to be doubly sure right now it's pretty sweet about this now that we have the server open let's show this this might actually be tricky for me to show without having them split so i'm going to split them in half here there we go and we don't really want that all the way over there this should be fine it's a little bit bigger text but bear with me for a moment so if we go into our index css file here now let's say that we change uh you know whatever actually you know what let's do this let's change the font size to 26 pixels so we're going to just enlarge the the base body of everything and it should get a bunch bigger now what you'll notice is that is live reloading which is pretty cool what you would really want to pay attention to is the fact that over here on the side these two logs that gets reloaded all right so let's do that one more time so we save that and you can see that they get refreshed you can also look up here but with when it's so fast and lean it's hard to actually see it sometimes you'll see that little flash on that reload yeah so that is live reloading working but what we really want that's awesome is hot reloading and to get that it's very easy now so all you need to do is go to your dev server and you want to say hot it's true now you might be used to package json when you run this like webpack dev server the old way or this way you could do dash dash hot flag here which i believe you can still do but it will automatically do that and it will also automatically load the hot module plug-in in the plug-in chain if you just set this so they've streamlined this to be a lot nicer now so you just add true let's actually make sure that that works why don't we i think we will need to restart let's actually make sure one more time yeah so we'll need to restart our server and then from here we want to reload this one just to make sure and then add that property again and look at that so you can see that it's just dumping more logs and how can we you know make sure that that's actually what's happening because it's happening pretty fast well check this out let's say that you were testing this out i know this is really squished sorry bear with me let's say that you were testing this out and you wanted this like really long title on mobile or something like that and and you want to see like how many times it wrapped or whatever this isn't a great example but notice that i've edited uh the html here so if i reloaded it would just go away right but if i add this to it notice it kept the whole title and if i undo it it will do the same thing so this is one of the reasons why hot reloading is really nice because now watch i'll reload and it's gone so it wasn't a live reload it was a hot reload not module replacement and you can also see that in the console if you want to see that it's working it'll say hot module replacement enabled now why this is really useful getting back to that if it isn't immediately obvious a lot of times um it will it'll be a little bit faster of course uh that's the first benefit just faster but also uh when you're making changes especially later when we add some react and you're changing like state or maybe you're editing the dom you're switching some things around or messing with stuff uh being able to you know live inject those css uh styles to not have to like replicate your current app state can be really really efficient and speed up your process a lot so yeah isn't that awesome just one little property now and you got hot reloading and this will also uh make a difference i should actually know as the project scales one thing i forgot as it gets bigger and bigger and bigger the reloading process will be slower whereas injection will be much much faster and that's where you're really going to see it so on to scss so in order to have a css now i'm going to go back to this format for a moment in order to have that we are going to need some new loaders of course but let's just change over to an a css file to start okay what we'll actually do is we're just going to set up some scaffolding for like a normal way that you do sas so i'm going to make a global.scss file and that is where we're going to copy over oh no you got rid of my other one index scss so we're going to yank all this over here put that in global and then what we'll do is we'll use the at use directive and we will bring in global okay if you're used to import in sas it's not really recommended anymore i think it's because it sets global variables but the new way and we're using dart sas so we can use this the new way to do it is the at use variable which will like locally scope it you'll see a little bit more of that in a moment so then what i'm going to do next is i'm going to make a variables file and i think most of the time you'd probably want to be using uh css variables nowadays but i will actually create a sas variable just to make sure that it's working and you might have some sort of use case for it still i don't know but typically i would lean toward css variables nowadays but let's make that uh peach buff right that was our rpg one and that's all we're going to have for now actually you know what let's actually do uh let's do both so we'll do root just to add a a global one here so we can just see that both are working and then uh have to do two i don't really recommend using both but like i said maybe you've got some use case that makes sense that's our variables file so in my index uh css we don't actually need to import the variables here like you might be used to we're actually going to go over to global and then in global we're going to use the use directive and we're going to say bring in variables and need to put a semicolon here of course and then you can just change this over to variables dot and you actually use the variables like methods from there you are going to use the dollar sign which is kind of weird pretty interesting huh and then here we're using a css variable and so we're going to just do text because that's what we set there let's uh try to run it let's see what happens here so we'll do npm run build and that's not going to work because uh there's no index.css file right i forgot actually to go here and change this to scss silly goose jimmy and from there we'll run build again we're getting another error this one is the the famous loader problem okay so in order to get that working uh we'll just go back to webpack config and really what we could do is just add this s here and if we wanted support for both we could just do a question mark here and that'll mean like it might have an s it might not now go back and run build here it'll build but we didn't actually add the loader right sass loader and all that so if we go and look at the output notice that it's just it just basically took whatever was there and output it it didn't actually run it like it like it should so in order to get that working uh all we need to do is add the uh we're gonna add sas and sass loader now this is dart sass uh that we'll be using there's a node sas package as well and this one's a little i think it's a little faster but also more up-to-date let's go back over to this and now we'll add sas loader and that should get us where we need to be okay let's see did it actually build cool yep and it's all minified which is interesting before our css wasn't and yeah you can see it's outputting the color just straight up which is interesting about the variable doesn't do the name and then this still stayed a css variable so that seems to be working now we might as well just add post css while we're at it so we'll just do post css and pmi-d and then post css we're going to do preset enb which is kind of like they will preset env but for post css just most modern browser stuff and then post css loader in order to actually utilize it now we will need one extra thing here uh we're going to want a post css config so we'll make that file we'll do post css postcss.config.js i always forget that one this is very similar to babel it should be familiar i'm going to do plugins and this is going to be post css preset env now let's get rid of all these now let's go to webpack what we want to do is add our post css loader and we're actually going to add that before the sas loader this is actually really cool this is something that a viewer from a previous video actually mentioned because in that video i'd mistakenly put them in this order thinking that it didn't really matter because i tested it out and i didn't notice anything and that's just what i like to do so they actually went and did a little bit of testing a little bit of research there and they noticed that uh not only would it kind of break some uh slash comments but the big thing was that it would take your vendor prefixes and it would put them into your source maps which you wouldn't want you'd want to see the original code so that's pretty cool thank you martin for going to discovering that i really love to see that people in the channel helping each other out and also helping me to grow as well it's really fantastic and now i'm more knowledgeable because of it so awesome now let's run build again see what we get now we'll go to our main css and this is actually going to be pretty subtle so i'm going to format this but you'll see here that there's this this one extra line here the color being output before this is actually the fallback that post css is adding in order to see it do a little bit more let's actually add some more code to our actual global what we're going to want to do this is some css for later i'm going to add for main tag i'm going to do display flex then i'm going to do flex direction column and align items can i do a i see yeah that's cool and then here i'll do button and this is just going to be fc 1.5 rem something like that bump that font size and then go back over run our build again and we're going to take a look at that i actually should be doing uh dev huh npm run build dev and go to our main css and you'll see that uh it's not doing anything quite yet and that's because flexbox is very well supported in most browsers nowadays which is really cool what we're going to do is add a browsers list rc to support a little bit wider range of browsers and that's actually pretty easy now the reason why you do this is i recommend sticking with the default if you don't really know any better you don't really even need this browser's list but what this could be good for is let's say that you know that your website's demographic is a little bit skewed differently and you have a little bit more traffic in some older browsers than most people do then you can opt into this stuff so what i'm going to do is last two versions this is just kind of the general syntax each line is kind of a rule it is a rule it's not kind of this is going to i'm going to target 0.5 percent i think that the default is one and then i'm going to do ie 10 which i'm very sorry for anyone that's doing that it's just for demonstration purposes i actually wanted to run build dev such a habit let's go back to main css one more time on whoa look at all this stuff yeah so these are vendor prefixes so these this is the way that uh flexbox was supported a little bit further back as far back as it can support it it's not gonna guarantee that you're going to get in every browser it's just going to you know you have to test that out unfortunately but you could look it up in can i use which is a great resource so if you actually if you're not familiar with that i might as well briefly go there um do that and then we'll do can i use go there really awesome and then let's say you wanted to look for flexbox you can come here and this is the important kind of stat to hover over is this is like global support from all the traffic that they look at like all browsers it's very well supported right now and you can see that ie10 has some like partial support with the prefix so that can be a good detection for us to say oh the dash ms prefix is what supports it but six through nine won't unfortunately okay so if we go back to our css you'll see that we have this dash ms flexbox and sometimes they behave a little bit differently so you still have to do a little bit of testing sorry that's just the world that it is but you know that it's working and you can use can i use to see which browsers support which and that also works for javascript as well and that's actually what these use out of the hood there's a package that serves up all those all that data and that's what browsers list and the babel preset a and b and post css that's what they're all using under the hood as far as i know so now just like that you've got some good backwards compatible support so you can use modern features and still support them in the old way like i said still have to do a little testing and if it wasn't clear uh this browsers list both fable and post css are both reading from that so they they'll they'll use this as this kind of global standard to say what are your targets there's other ways to set this up but i think this is the nicest for me just to be able to quickly see what this project supports now unfortunately as of right now there is a bug in i believe it's in webpack dev server or webpack five i'm not sure actually but it's caused in the modern versions uh by a browser's list rc being set there and and then not being sent over properly to your production and starter build so let me show that just so that you can see that and in case you want to check if you actually have it because maybe in the future they'll have solved it and you won't have to worry about this but for now i'm going to give you a fix so if we do npm start all i need to do is go over to my browser we don't need this anymore or reload this server [Music] and then what i'm going to do is try to do some of my webpack library loading here so let's say i go to um we actually actually be able to do this just from well let's make it easy so i'll just say like um fc 100 right just do a big old change now when i do this and i come back over here uh you can see that it didn't do anything unfortunately so i'll change that back again maybe let's do something uh you know different here maybe let's say let's change this to purple why not nothing unfortunately what if i reload it's there so this is the bug that it creates and it's really unfortunate but i'll show you a quick fix so what you can do is you can go to your webpack config stop and then you can you have this mode set to development let's do a target and this target is going to be default to web now this is the default uh already just so you know but the reason i'm going to do it that way is because then i can come right here and i can say target is equal to target and then what we're going to do is say if you are in production i want you to actually target the browsers list that's the setting and what that's going to do is going to make it to where when you're running the the dev server it's properly set to web but when you build it'll still use the browser's list and output everything correctly if it's in production okay so let's make sure that's working first let's check our live reloading i'm back here we've got this peach puff right and you can see live reloading enabled there is it true though hmm i don't know let's find out um so i will just change this here to purple again it's probably the most obvious right and then it auto reloaded pretty cool just flip it back there you go so it is clearly working and that's awesome but what we should also check just to be diligent okay so if we run npm run build that will be production right and so that means that if we check our main css at this point we should see this big long minified version and we should see all our vendor prefixes that's the important part because browsers list was the one causing it and we do see them so what if we do npm run build dev just to be extra sure it looks like we're still seeing them now like i said that is a a temporary fix right now and hopefully they will have that solved soon so make sure that that issue actually exists for you before you apply that but hopefully it will be fixed soon all right now in order to wrap up the css section it was hard to say i am going to make sure that i do my due diligence here and commit these files real quick as a quick refresher here so let's go over to browsers list rc yes we did add that we don't worry about our package json and then here uh that was the lock sorry css loader and then the mini extract plug-in yeah we've done a bunch of stuff post css post css loader looking good all right add that we added a post css config so that it would look for that preset env we then updated our webpack to have the mini css extract plugin setting our target web for the fix and all that good stuff and then we set up our rule for scss and then from that point on and actually you know what uh i'll make one little modification here while we're at it if you want a more universal like test scenario this one's fine there's nothing wrong with it but we can actually do is let's go back to where we just had css and then you can do an interesting little fix here where you can say well what i want to say is let's let's wrap that so this will kind of set up some options and then i could say it's either going to be s css or just css and you can take that a step further which is pretty crazy and say at this point it has to be an s or an a okay and then that will make it to where it now says uh it's gotta start with s and then the next character could be an a or c and then uh then it'll be either that or a c and then ss so this is supporting sas scss or css so if you want a kind of global solution just you know because it's easy and you can use it every single time then you can go ahead and use that all right sorry let's finish up and that puts our rule there we've got css loader post css loader and sas loader remember that you want your sas loader to be at the very bottom which is the first thing that's going to enter and then it'll add your prefixes to your css and then finally output it into a file and then down here you got to have that plugin and we got hot true we've got our hot reloading lots of fun stuff we imported it into our uh javascript file and if that wasn't clear that was because we we need webpack to actually see it to process it and this is our entry point so that's why we do that then finally we set up our global css files i'm not too worried about reviewing those too much we know what we did and we're using that at use directive cool so let's say add css sas host css hot reloading all sorts of good stuff and a browser's list we should probably add that as well if you're actually being diligent about your commits you can do a big old message but i think that's fine for now all right now it's time to get some react and jsx working in our project but first i would highly recommend you take a standing break or and a quick water break get some hydration going on in just a few minutes you know stretch your legs out and it's just a good habit and then come back refreshed and ready to set that up all right to start off now we're gonna do uh npmi react and react dom one too many spaces there now this is actually not going to be a dev dependency because it's going to need those packages in your final output i actually don't think it really matters in webpack world in this situation but the standard convention here is that these libraries will actually be used with the code that the client downloads so they should be in production just so that it's clear to everyone next in order to transpile a jsx here we're going to do at fable and then it's slash preset uh react yeah so we already have preset env we're going to add preset react now to get that working and so let's head on over to our uh fable file here got all these things open let's just do close all go to babel what we would normally do is we would just add it here and say at table slash preset react and that will work however we're going to do something cool and new and fun so in order to do that we are going to put this extra array around here a little bit weird extra array around that and then that will stay the same but we're going to add an object that's in the config option here and then we're going to do run time and this is going to be automatic so what is this well uh since react 17 plus and they've been part they partnered with babel on this the team that does it does the tool set there is a way now to actually opt in to not having to import a react whenever you're just using jsx in a file which is really cool and under the hood it actually is supposed to make it a little bit more efficient as well and so the only time that you'll need to import react is when you need methods or state or anything like that from the react library you'll see what i mean but just so you know why the settings there it's pretty cool now let's modify our index.js so what i'm going to do is i'm going to add to the index.js i want to import and i'm going to do a d structure here we're going to do render from react dom so we will need to import that and then right here underneath this i will say i'm gonna call render and just to test it out i'm gonna put an h1 here and we're gonna say oh hi from react and then here the next part is gonna be dot get by id you can just do that as a shorthand if you type it right and then so when you get element by id you can do you could do query selector as well this is just pretty normal and uh that will make it to where we attach react to our dom but in order to make that work we actually need it there and so we need this we need an element with root or whatever we want to call it roots the convention come back here document get element by root we'll attach this h1 to it and then that should work so let's try to run it so i'm just going to do start and then go back over to our server oh hi react yeah got it working pretty cool notice that we didn't need react in that file but you'll see that uh in the next file that we're about to make as well if you don't believe me so next let's actually make a component here let's come over here we're going to add a new file on the side here and in source i'm going to make a new folder and i'm going to call that components that's a pretty standard convention you can do it however you like don't don't worry about you know having to adhere to whatever if you've got a preference you can but if you don't know what you're really doing or you're not opinionated this is pretty normal until you scale to a certain size so in the components we're going to make an app.jsx which is also pretty common and i'm also going to make a well here a recipes.jsx for our recipes and that's so that i can come over here and i can take all of this code steal that go over to recipes just put that in there for now we're going to do more with it in a second and then also let's go to here and i'm going to take this css and then put that in app i guess it could stay in the other place but this is fine and then what we'll do is we're going to import app from dot slash components app cool notice that i made that with a app and recipes dot jsx extension you don't have to do that you can do jsx it's just if you want to it's a common convention i think a typescript you have to it's tsx in that case but either way you don't have to but notice i'm also not putting dot jsx here right i just want to import it as a regular javascript file that's going to matter in a moment so then let's actually make that a react file so in order to do that what we'll do is we're just going to start with app and get that working uh i have a short hand here for my snippet library snippet good for checking it out i need to actually update it for react um for the that latest stuff that i just showed them not needing it but either way we'll make an app here and then this app we might as well just you know i'm going to set it up as the way it should be here so i'm going to change this to um via fragment and then i'm going to set section and i'm going to set the class name uh this is just some scaffolding for a moment later we're gonna set this to hero that's our section and then i'm gonna do main here and then in that main i'm gonna have another section and h1 this is where we'll do oh you know well hi react and then that's it for now then we'll go back to index.js and then here we will uh let's see actually no we don't want that tag either we want app we're just going to load app what can i type let's see if that runs did it fail module not found cannot resolve components app but you know let's just make sure that it wasn't just the server flipping and you'll see that it failed can't resolve this file why that's because it's looking for a dot js automatically so all we need to do to fix that situation you could just type the jsx if you want to and that'll work but what we can also do is come on down and say okay let's add a resolve property and that resolve property has a bunch of different other properties it can have but you can do extensions and for extensions we still want to support js and we want to support jsx okay and now when we do this this will make it what this is doing is saying whenever you import something you don't have to have that extension it will automatically infer and you can throw more on there if you want this is just what i usually do just those two so let's run build again and see that it works no it does not because we don't have our loader setup but at least it saw the file this time okay so same thing we got to the jsx see that fragment there it's saying i don't know how to handle that okay well i'll show you webpack i will show you so all you have to do actually now is come up to here because our babel is already set up to handle react or jsx in this case and so all we need to do is add an x here and we can just do a question mark like the forward say it may or may not have an x now let's do run build again oh yes index scss so we moved it to app which means that we now need to go up a directory because we're in components right now so we need to go up from components and into styles sorry about that and there we go awesome so let's just do npm start now since we've got that all configured we'll get our live server loading make sure this is still running and then notice we have the centered thing because i created that css for the the main section here and it's just centering that oh hi react so that's working right but next i want to set up our recipes and this is important for a little demonstration i'm going to do that's why we're doing that so an app we can import we actually don't need to import react that was the thing that i was going to show you right will that work or will that not reload still working right pretty cool we don't need that uh because we're only using jsx right that's that's the key thing here and you'll see in a moment when we do need that that's why i'm gonna set up recipes one reason why i'm gonna set up recipes so recipes okay we can do the same thing here i'll just do you know rv and then i'll say recipes for me so you're going to have we we will not need react but we'll we'll actually need i'm just going to use this we will from react need use state okay and in this situation the example i'm going to set up real quick i'll probably just speed forward through this to save you the time of watching it so we're just setting up some state here and i'm going to set up a couple of buttons to swap between the two different objects that we have and then just list out all the properties and really the purpose for this is to just show the persistence of state when we get into some hot module reloading and stuff later on in the video and that should be good and then in app i want to import that so we will say recipes from dot slash recipes and then we'll just load that right here underneath so recipes oops oh okay and here we go those are big okay so now we have we click this and we click this and you can go between the two states if you reload you'll see that uh this one loads this object and this one loads this one so our react and our use data is working we're compiling jsx and as i said before you do not need to import react whenever you aren't using state and that's pretty cool and it should be a little bit more efficient as well now i almost forgot let's actually add these files and do our quick review of what we've done so we've updated our babel to have this runtime automatic here and that's with the reset react of course let's go to stop that let's go to package json and we'll see that at mabel preset react was added as well as the react and react dom dependencies we go over to our webpack config we can see that the jsx test has been added we just added this x character to look for those files instead of just javascript and we've also added the extensions for js and jsx so that's cool now for our index.js review that we brought in our react dom so we could render it and now we're importing app and um just so you know some people uh you know like to put index.js not jsx here even if they're using the jsx syntax because it's not quite a component necessarily i've seen it different ways i don't think it really matters too much this one is just demonstration purposes that you can do both right now but you know do it how you like moving on the app pretty straightforward and it includes recipes so we added that component and then recipes this is our stateful component just so we can showcase you know when you do need to bring in react you'll need to bring it in if you want to use use state okay now for this commit message i'm just going to say add react support something like that do whatever you like push that up since we haven't pushed in a little while so that'll wrap up that section and the next thing that's going to be really common in our app that we're going to want to support is images now if you'll recall i made this section with a class name of hero before intending to be a sort of hero section with a background image and so this is about the time that i normally would want to bring in some images so i'm going to actually copy some over just to save us some time here i've got this folder that just has a bunch of images and you can see it's a various different extensions because we're going to you know make sure that we cover some different ones and not just one type and then what i'm going to do is i'm going to make a a whole new file here and i'm going to make it hero scss and then what we'll do with that is we'll target that hero class and we're going to have a background and you can just use this uh which is really cool when you're using webpack project just like a relative import for where you are so in this case let's say you know we're going to go into images and then we're going to do the swc banner and that's going to set the background so if this isn't already obvious a kind of cool note that i like to point out here is that you know we're able to import this like you know sanely from a relative path because we're working with our source code but eventually that's going to be output in this distribution folder and those might all be flat or they might have different locations the main point is that uh everything's going to be different on the other side and webpack's taking care of that for you in the final output which you'll see in just a moment so now that i have this set let's uh do some basic css as well just to make it look a little bit better so i'm going to go uh bgz make that actually cover background size cover and then can i do bgp i don't even know oh yeah you can but we'll do center min height and for this min height uh i'm just going to do 300 pixels and then finally we'll do a width of 100 percent i really wish that the w100 oops w100 like didn't do pixels but i get it oh and let's not forget that we need to import this so we'll say at use hero and that should be good now let's run this and we should see an error since we haven't set up anything for it yet it's a pretty weird error uh it'll it's right here is module parse error module parse failed unexpected character and this cute little question mark diamond and it's also letting us know that there's it needs an appropriate loader again i wish that it could tell us a little bit more information about the type but it doesn't unfortunately so it's just the way it is maybe it's really challenging now how you would solve this in the past was that you would use a file loader or url loader those are the two plugins that i've always reached for before but in webpack five it's pretty cool there's actually a built-in way to do this without any extra packages to be installed and i'll show you that right now so what we can do is add a new rule to our rules list here and this rule we're going to do a test for it just like normal and we'll make that case insensitive because we might as well and then this test is going to be just like our other ones but this time we're looking for file extensions right for images so png you can do jpg or whatever you're specifically doing you can also just do this so that like optionally it has the jpeg or just jpg then we're going to do gif gif or whatever you like to say and then svg and then here uh we're just going to say it ends in one of these so we're looking for all these types of extensions so we can kind of do a good catch-all for all those now next normally we put a loader here but actually all we have to do is say type and then i'm going to show you the first one here is the asset resource okay so notice that at this point this is what our disk folder looks like and i'm going to flip over here npm run build again so we get one more error here and if we come up here we'll see that this automatic public path is not supported in browser and you need to look up one for this mini css extract plugin as where it's happening this is a pretty good gotcha i got stuck on this the first time i did it for quite a bit let me show you how to get around this so what you need to do is this mini extract plugin you can pass these in as a string or just a series of arguments like an array list but you can also pass in objects for each one so i can move that up here and then what this will be is this is going to say this is the loader and for this loader we have some options and that's why we need to do it in an object and for the options we just need to put public path quote there get rid of that line and that's all we need there was a point in time when i knew what this did this public path here uh but i was messing around with it the other day to try and refresh my memory and i can't for the life of me remember exactly what it's for but i know it's required at this step um so if anyone has any super cool knowledge about that that you want to drop in the comments i'm sure everyone would appreciate it i definitely would i'd like to level up myself so that should be all that we need let's run build oh uh looks like i must have typed something wrong [Music] probably options oh yeah we got a typo sorry happens though npm run build again and there we go so now if we go back to our folder we will see that there is this image sitting out here now it has renamed it with this little hash that's normal but it will be the exact same size as the original i don't know if i can show you that it might be kind of hard to see but this 226 kb here if we go to our images and we look at this banner it's also that same size so it hasn't changed at all there's no compression or anything going on at this point yeah so now we have that in our gist folder and if we were to let's go back over to our server if we go to our server and oh well i didn't start our server today well we can just look at the built one and here you go there's this little image and it's using the background position cover it's pretty cool and if you inspect it you'll see that the url now points correctly to where this file is on my system that's that's the gist of it now the other way that you'll commonly use images in webpack is just through the standard import actually i meant for this to be up here let me move that for just a quick second and then what i'm going to do here is just say import and then we can name this whatever we want so i'll just name it sword from and i'm going to go look up one directory into images it's still a relative path here and i don't know why i don't get auto completion on this one it's kind of weird because you do in the css i'm not sure if that's just a configuration thing but we can go over to here in images and just say okay we want the swc sword png so we'll use a png for this one swc sword.png and that this is just actually going to be a regular image tag so we'll go image change that source to uh javascript and say it's here and then alt will be sword and then i'm actually going to give it a width just to like to cap it out here and i think that this will be about 250 pixels so just to quickly go back over this this is importing this as a path if i were to console log this it will actually be the path to that file currently and so that's what's going to happen when we run this and let me i'm going to do build for this just so you can see the assets each time rather than running webpack dev server so i'll build this again and there's no extra configuration needed we already have it set up the only one we needed was that extra css property but if you go up to the top here you'll now see these two images you'll see this the sword that i just output and then this background and if we go to look at it in the browser you'll see the image is now loaded there and it's going to be the same it's just going to be a file path that it finds okay so what's another type of image that we commonly want to bring in here would be a svg so let's make sure that that works so from dot slash images will do this exact same thing but this time this one's just called sword.svg and here we will copy this sword svg everything else can be remain the same we're going to run that build again let's go make sure our assets are there and here we can see this svg output and it's also all hash and beautiful and then if we reload we'll have two copies of these images one's an svg and one's a png and actually let's take a look at that now there you can see that path and now i'm just going to set up one more quick demo and that is going to be here in the global so in the global what i'm going to do is i'm going to target all uls and i'm going to make the list style image set to a url and then that's going to be my tiny little image here that's this dot dot slash images slash and then there's that 32 by 32 and this uh the purpose of this will be revealed in just a moment and cameron build real quest and then we will go over to our browser and we'll reload this and then when i drop this down you'll see these cute little sword bullets that i've made just to show that now why i'm doing that like i said you'll see in a moment but coming back to this if you would want to actually put these you can see how we have all these like files right here in the root let's say that you want to put those uh for cleanup purposes into an image directory just to be a little more organized i should say what you can do is you can add the output path or the output property here and then just for that output property you can do asset module file name and then do images here and then what they want is this is just the something i copied off of the docs i know the hash and the extension it's just those brackets are saying like that goes here so we're going to anything that any asset that comes out just notice right here these assets are going to go into this folder images here and then this last one that they always have is query and i'm not sure what that is for but they always have another doc so i put it in now if we pop over here to npm run build uh we will wait to that finishes come back here and you'll see now there's this image directory that has all the images in it now of course you'll notice that all these old ones are here and so what we'll have to do is delete all of those and that is you know less than ideal and we're going to fix that in just a moment but for now we have all of our images in this folder and it's a good opportunity to show you another type of thing that you can do which is set this to inline so asset resource is going to output all of these things asset inline is going to actually inline it into our javascript so i will delete this directory just so you can see that and then when i come and run npm build one more time you'll notice that we get this warning and it says in asset size limit exceeds the recommended size limit 244 kb and can impact web performance and that's very nice for them to tell us that now let's actually see are things still working yes they are you know we have all of our images but look at when you hover over them go away it's this like big old crazy string and you can see it says data image png base64 and what that means is that it has actually been inlined into our javascript bundle file so if we go back here we don't have any images in our disk but if we were to look in main.js and then let's just say we do a search for base64 let's say and here you can see this data image png base64 data image svg base64 so it's actually taken and made them all this base64 encoded text output and put them all into the javascript bundle now that is not good to do for what we are doing for this purposes because those are rather large resources and that's going to make our initial bundle very large and time consuming to download but this can be really useful if you only have really really small images and that's because there won't be any additional requests required to hit the server for any of those assets and it won't have to wait to kind of parse them out as it hits them in the dom they can just be loaded right off the bat so maybe if you have like a bunch of little small icons that you want to load in the header really quickly that's a good time to do something like that so that's the gist of asset inline but there's a really cool little generic property that you can do that's just asset and how this works is webpack is going to automatically determine based on a default max size which is 8kb according to the docs whether it should be inlined or whether it should be in the image directory so let's try that out real quick npm run build okay come back here notices we have an images directory now and we only have these two images in here so we have this banner and then we have this picture now the svg and those those cute little sword icons that i made those are smaller than 8kb let me show that those work just reload yep there they are and if you look at this one it's base64 encoded for this and if you look at this one it's just a regular file path okay and if we go to the bullets let me show that in the url oops uh here we can see that it is this base64 encoded drawing it from the javascript bundle and so these can load really quickly if we needed them to and the rest of them can just be resources in the in the final scheme of things so i'm actually not sure what the most optimal way is to do this my assumption would be just to leave it on asset as a default or go asset resource but i think uh sticking to asset is probably your best bet that's what i would initially recommend but it probably depends on your use case and what you're doing so if you're starting out either asset or asset resources is probably the best default way to go let me show you one extra little thing that you can do that's kind of cool so you can say parser add this little key and then do data url condition and then what you can do is max size 30 times uh 1024 now why i'm doing this is uh we're our normal max size is 8kb but i want it to be 30 and you know that's 10 24 bytes times 30. it's just a little easier and that's what they do in the docs i think it makes sense to mentally math and from here i actually have uh made some of these just around that size just to show that point so if i npm run build actually you know what we are going to need to delete this first aren't we so let's delete this and what we should see is that only one of the images the big old banner image should be in the final output let's see if that's right yes it is just this banner so now we've taken that png sword that used to be there and because i've raised the max cap you can now inline that i you probably don't want to be dabbling in that unless it's like a small size adjustment and or you just happen to know that that's what you want but that option is there and i just want to show that so i'm going to take that out and we'll go back with the default now of course you could split these tests up if you want to handle different things in different ways you might want to break out your svgs into their own and just you know make those all inline there's a lot of customization that you can do of course in webpack that's the whole beauty of it and also the double edged sword where it can get really complicated and i also want to mention that i i did not add support in this for inline svgs we only have the image format to an inline svg is where it actually writes the svg code into the html which gives you a lot more power if you're trying to like change an svg uh with css but that option is available to you i'm not going to cover it in this video as it's going to add a little bit too much time to it but just know that that's out there in case you want to dabble on that but for a lot of people's purposes the svgs just loaded in as the image are going to be fine because you're still going to get all that vector quality but then you can just treat it like a normal image resizing and all that so that wraps up this image portion for now and it suits our needs but i'm getting pretty sick of deleting this images folder and individual images over and over again as i'm fiddling with the config and such so what we could do is we could go into our package json and make a little clean script and let's say let's make this clean and then what we'll do is we'll rm maybe say we do uh dash rf and we do disk you know something simple like that now the problem with this right now though is that it will delete our html file and that's not tracked and we aren't generating that it's the only thing we're not and so that's the next thing that we're going to tackle so that we can get a sort of a purity situation where every time we wipe dist and we build it from scratch and that's going to make it to where it's a lot more realistic for setting up on our server so let's make a quick commit just to review all that stuff and yep we added this little clean command that we aren't using but we'll keep it around just for the fun of it we learned about making a custom asset module file name directory here so that you could put all of your stuff in images we obviously learned about the asset type and catching all of those and then we had to fix for importing our images through css we had to fix this with a little options config a public path and so that's all for that file and then of course we added our images here not too much to see there we added all of these images now we didn't actually test an import of a gif we should have done that just to show that that works and then for our global css we added this little style just to be able to use that uh in our hero well we added this new thing and then we imported that in the index that looks good to me so i'll say add image support to webpack pop over here get push origin main and now we're ready to generate out our html files from a template okay so what we're going to need now is we're going to do npmi-d and we're going to want to install html webpack plug-in very common plug-in in this world and then what we'll need to do is go over to our code and in our webpack config js now we're going to want to import that first so we'll say const and then that we'll just call that html webpack plugin pretty standard here and then we're going to require that and that's html webpack plugin and then we'll go down to plugins here i don't know why i went back up there and we need to add that to this uh plugins array so we'll say new html webpack plugin and call that and i'm not going to pass any options just yet so i'll show you how that works in general but what we will need to do is we're going to take this index html we're going to drag it on down just into source and move that okay and that's going to put that here and make it tracked now just so that we can save that and then when we go over here we can actually be crazy and run npm run clean that script we just made and that's going to remove our dist folder which is kind of scary so now it's gone but if we run npm build all these things will be generated out you'll notice that there is this breaking change error we're going to fix that in a moment but let's just start with this and show the dist folder has been created it's got images and look it has an index html now if we format that to actually look at it it's cool that it's been minified and all that but you'll see that it has uh automatically added main css here and main.js here you might notice that it's missing our little root id tag that javascript or that javascript that react is attaching to and that's okay we're going to fix that in just a moment but this is pretty sweet for it to automatically detect um that we're going to have a main css and a main.js and just put those right into it cool now also notice that it says webpack app and i believe our said webpack project so that's different as well it's just the default so i'm going to close that for a second and then what you can do here is you can add an object when you call this and you can set template to a template and this just takes a relative path and it's going to go to index.html for us so we're going to point it at that file we just copied over because that has our div with an id of root that's really the only thing we need but we might add other stuff in here as we move on so this is our template that we're building it from so let's try that again and what we'll do just to test it out here is we're going to delete this for now we're also going to have well we'll do it with our script we're going to have a way to do that in an automated fashion in a moment but for now let's just do npm run clean and then npm run build let's go take a look at that file as soon as that finishes and see what happens so now our index.html formatted again is it's got duplicates so it does have our id root but you can see that it's injecting these things for us but then we had them to start with so all we need to do i just want to show you that that's kind of how that works all we need to do is just remove these it's going to take care of any of our dependencies like that for us which is pretty sweet okay and then that takes care of that and then the the error that we're running into before this breaking change thing hopefully um in the future soon this will also be solved but there's a temporary problem where html web pack plugin is producing this error that you can fix by doing i dash d and then when we install html webpack plugin you can do at next and that's going to do like the latest beta version so we'll see as soon as this finishes it's going to do beta minus 5 0 0 beta 6 in case you end up following along so i showed it in this order because i don't think you should install it with the next flag unless you actually have this this breaking change thing you can just stick with stable because by the time you watch this it might already be fixed i'm not sure but from there let's just try it one more time this is hopefully the last time we'll have to delete this bucko and then we will npm run build i guess i could have used my clean script i keep forgetting that we just made that and there we go and that error is gone awesome now we could solve this next problem of cleaning automatically instead of having to do it manually by going into here and saying okay well when you run this you could do npm run clean and and but then you'd want to do that on pretty much all of these and also with the webpack like uh serve doing it it's only going to run it on the first time we want to kind of do it on every time so there's actually a really cool plugin that will take care of this for us instead of us doing it that way called clean webpack plugin so we're going to add that clean a pack plugin now we'll need to update our webpack config for that as well so we're going to bring this in and this one's actually going to be destructed from it so it's clean webpack plugin oops and that is going to be brought in from clean webpack plugin now same song and dance here this should be getting kind of familiar to you this is how you handle a lot of plugins here is we're going to do new now i think this has to be at the top i've always seen it put at the top in most situations i haven't actually played around with i should sometimes see if moving it around makes a difference but i just recommend putting it at the top for now and so we just need to add that on to this the top of our array and then now when we run npm run build you'll see that we get this little bit of a warning here that says clean webpack plugin options output path not defined the plugin is disabled so unfortunately right now with this plugin what you need to do yet another thing that may be fixed is you need to add a path property to your output now normally you don't have to do that a lot of people do anyways and that's why it's still around webpack 5 was the first one where you didn't have to do this i believe but for this plugin they haven't updated it quite yet to that state so maybe hopefully soon but what you can do is you're going to do path dot resolve here and like i said you don't have to do this normally if if it's the default path but if it uh you will commonly use this if you want to change your output path so if you want to change it to not be dist and you want it to be public you know you could just do that here now let me break this down real quick for you while we're here actually you know what let me get this working first and then i'll do that so i'll say const path equals require path now if you're not familiar with this this is just comes with node you can just require it you don't have to install it but let's see if this works oh did i do whoopsie that was supposed to be a string dist whoopsie daisy sorry okay and we don't seem to be getting the warning that it's disabled anymore and uh we can look and see that our stuff was output fantastic so now uh you know let's actually let's make sure so to be certain let's add some gibberish file.txt right and then this will be right here and then if our plugin is working right and i run npm run build it should remove that because it removes the whole folder and then build out all our code into there and you can see that file is gone so pretty confident that it's working there right okay so this is a pretty common uh point of confusion it was for me for so long and i still even forget the gist of it every now and then so i want to go over just really quickly this whole path required dur name thing because it's kind of weird right that like we can use a relative path all over but for some reason we just start doing it right here let me actually show you you know the best way to to learn is just to break it so let me actually show you what if i were just to say well yeah go put it in dist will webpack care yeah it actually says uh initialize using configuration object that doesn't matches and we can look at dist is not an absolute path that's a pretty good error actually so it is telling us that it wants an absolute path now if you run node just regular old node right in the terminal here what happens if you type path dot resolve and you call that you'll see that it automatically resolves to where we currently are an absolute path and then if i were to backspace and just put dist from there you'll see that it resolves the absolute path to dist so that's what path.resolve is doing now kind of a gotcha here though is that if you were to cd up one directory and then we're going to do node again and path.resolve see how it's telling us that it's going to be only up to this point so what path.resolve does is it's wherever you're running that script from you can also use cd dash space dash here to go to the last folder you're in just a little trick there so path.resolve is going to give you an absolute path well what is dername therefore well their name is the directory of which the file that you're running this command from that where that directory is so that's just going to give you the directory but then path.resolve is going to give you the absolute path to that directory so that's why you need these two combined in this situation because uh during only as far as i understand only exists when you're running a script so essentially what we've put all this together for this nice little path thing this is a really common pattern in node you're going to see it all the time is that we just want to know what's the absolute path to the directory that this webpack config is so we can build everything from there oh another thing to know actually is that this path resolve way is also going to work universally across different operating systems as well which is useful for that purpose so i'm out of my depth to really explain much more than that that's the just what i know about it but hopefully that gives you a little bit of insight a little bit of clue into it in case you didn't really know that or it's a little bit of a refresher for you i need one every now and then now let's seal the deal here by uh going in and adding these last files here so in our package json all we had to do is add this html webpack plug-in and clean webpack plugin and then for our config we obviously brought in path we brought in the html webpack plugin and the clean webpack plugin we had to set up an output path in order to use that and then down here we added it to our our plugins array and we have that template and then we should also obviously be tracking the index html template that we're using now so there's that and we will say add webpack clean and html plugins push that up and now we are in a very good position with the addition of these recent plug-ins and the fact that we have this set up to where our dist is wiped every time and then rebuilt and everything from it you know comes from our source we can now host this okay it's finally time to deploy this on a server which is pretty exciting so there are plethora of ways to host this but we're going to use netlify because it's going to be really fast and it's so awesome that it's just the clear choice for me honestly so let's go over here to the browser again so let's head on over to netlify and you just search that in google and get there and it's going to ask you to log in and if you don't already have an account you can make one with github i think that's the the best way to do it or it'll just ask you to log in if you already have one and so here we go this is how it works and if you're not familiar with netlify just a real brief introduction it's really popular for hosting for the jam stack or any sort of like static files and since we're using a pretty simple react single page app this works great for us so new site from git you can go to github and it will usually add a little github plugin for you you can say configure in the netlify if it doesn't show here let's see if we see webpack project we don't that's because i'm not sharing all of them you can choose to share all repos or select ones which is pretty cool so if i come down to here and i say webpack oh yeah mine's config right so we're going to add that to the available ones save that and now my webpack config i click that and what's really cool is it is going to know the branch to deploy from now that's going to be whatever branch like typically you're going to spawn off from your main or your master or whatever and then this npm run build it detected as the build command is not really sweet and then the publish directory is dist it just did all that for us so now we just click deploy site it's pretty amazing and what's really sweet about this is that it adds continuous integration for us which is really awesome and what what i mean in particular about that is that every time that we push to master it's going to auto deploy a new version of the site so what it'll do is it'll build it if it has any errors it won't host it so it won't break your current site if it have you push up an error but if it's a successful build it'll spin down your old one after it replaces it with a new one which is really really awesome now let's go to that build and run build post build command now the fight build complete cool and then that that'll show right here published so this is your url now you can obviously buy a domain and set up all your stuff and ssl certificates and all that we're not going to do that in this one we're going to make this pretty quick but look at that we're hosted now so does it work yes it does you got your cute little javascript clicks i need to get rid of these images so that it actually fits on the page and then let's go see if you know our script's running yes you can see our objects here it's really cool uh this is just a fave icon we don't have a feedback on classic 404 all right so there we have it and we're hosted that was really easy and really cool all right so we've made it all this way we have our site hosted and i have one last thing to share with you i've left it to the end because currently it's in an experimental phase for webpack but that is for react fast refresh so react fast refresh is the new hot reloading thing for react that is really really cool it's going to be supported by the react team dan abramov has been working on it for quite some time doing a lot of cool integrations with it it was originally developed for react native and it's just kind of coming around to the web as support grows for it but for now there's an experimental package we could use that works pretty well so far so if you're not interested in seeing that set up then you can call it good here and that's fine but if you are interested or curious at all you should stick around because i'm going to show you why it's pretty cool and there's a little gotcha that i ran into setting it up for web pack 5 that i'm going to show how to get around so to show this first i want to show what are we solving with this well in our project if we say npm start and we start that up and we're going to go back to our local host server okay we have this setup and actually to make this a little more clear i'm going to get rid of these images temporarily and i'm going to get rid of these two just so that you can see that on screen all right and then i'll go over to the console so you can see what's actually happening here so it says hot modular replacement enabled as we showed before and we know that's working for our css and if we click the different state positions here well what happens if we were to change the text here and i think i should probably do a side by side for this i think it's going to be the easiest oh man it's so so crushed this is going to be tough okay if we let's say that we click the state and we want to see that state here staying there and then we want to change some text how are you why did i type real stuff there i don't know instead of gibberish notice how we saw some stuff loading and then it hard refreshed the page and we lost our state and that's why let's do that again so watch when i save this file you can see this little guy respin and then this whole log will reload once again so live reloading is working but we don't actually have hot module replacement working but i do want to show just to be clear before i move on that if we click this state right here and we say change oh i don't know the global fc to 20 what did i do 26 before save that yeah that still works and it still keeps the state so our sas any of our css hot reloading is still currently working it's just our javascript that isn't working right now our react in particular so there's already a hot reloading for react that you can currently use but this is essentially uh the new cool thing that the react team's been working on they've mentioned that uh they've there's been some bugs and issues and even uh like typescript support issues with the current hot reloading plug-ins and stuff like that and that's because it wasn't actually like maintained by the react team and so this is what they're working on now and like i already said uh it's in react native supported but the the support in the browser so far is kind of limited depending on your bundler system but someone's been awesome enough to work on an experimental plug-in for it and so that's what we're going to throw into the mix right now so in order to install that this one i am going to copy over because i'm never going to type this correctly so if you're following along you might want to search react refresh webpack plugin to go find it or the name or you can just obviously type it in 3ms here but we're going to install that which is the a person who has been kind enough to set this up for webpack and getting that going and then react refresh which is actually from the react team here so we're going to install those two packages now what we're going to do is we're going to go over to our code and we're going to need to edit our babel file first so all you need to do is go to plugins and then you're going to do react refresh slash fable and then you'll also want to go to your webpack config and then you're going to want to bring that in just like the other plugins so in this case we'll do react refresh webpack plugin it's a mouthful to type and then we're going to require that's this p what was it at pm such a long name there we go and then scroll down here to uh our plugins and we're going to throw that into the mix so uh i don't know if it matters exactly what position that you put it in here actually i'm going to put it here at the bottom oops react refresh webpack plugin save that and let's try and run it npm run and actually this would be npm start right because we're trying to get hot module reloading okay this is where i got got for a little bit now i'm going to show it just so you can see now let's reload the server here so it says hot module replacement enabled and live reloading enabled so let's see if that's actually true for now let's just go to our app jsx and here let's try the same thing i'm going to just click something to get some state on the page and then i'm going to type some gibberish and save and look at that it didn't actually change our title at all it said uh that it it hot reloaded here and it didn't refresh the page but it actually didn't update anything either i'll do it again just so you can see it doesn't really update anything blah blah blah that's really unfortunate i almost gave up on this one but after a little bit of splunking i was able to come up with a solve for this thanks to trusty github issues and lovely people there so the solve is actually pretty silly uh what it is is that um they were not counting on the fact that webpack five you don't have to put an entry point anymore if you want to use the default so unfortunately we will need to add that now and we'll say the entry point is source index.js so you can use a relative path for this one why i actually don't know output seems to be the only one that really requires a an absolute path so let's try that again pm start restart that server and let's see what we get go back to app so hard on this squished view reload this just to make sure that you've got the current one click some things and then let's see cross our fingers yeah look at that so now when i change things uh different html or text or whatever i can even uh i'll go into the let's say recipes one and i can go down here and i can change this to whatever and you can see this button change but we keep the state so that's really cool so that's all it took uh that will be the fix it's a pretty easy fix thank goodness i mean you know it doesn't feel very satisfying considering the hours that i spent trying to look it up but you know there it is for you i don't know if it was actually hours it felt like an eternity um but yeah now we've got that working now let me show you how cool this thing is so the first thing that i think is super fancy here i'm going to get rid of this just so that you can see it a little bit better is what if you have an error when you save what's going to happen is it's going to tell you exactly where that error is happening and then if you just go and fix it and save you get your app back now if you didn't notice that this is pretty crazy your state is still there let me refresh so you can see that so i'm just going to like you know make some sort of syntax error i'm going to save it tells me where it's at i'm going to re-save here we are now i'm going to click this button so we have all four of the bullet points and you know let's just i don't know what's something that we can delete it doesn't really matter we'll just delete that okay we save that and we're still keeping our state that is awesome now this also supports react hooks which is worth mentioning because with hot reloading the old plug-in you had to do additional work to get that support and this just comes out of the box which is fantastic and obviously you're seeing that right now but i just want to point that out now in order to show um a cool concept and to illustrate this a little bit better i'm going to create one more component and we're going to name this whatever.jsx we don't really care and in this component i'm just going to copy paste some code to just make this really fast paste this save that and then i guess in my app i'm going to import that so i'll say import actually let's see if it'll auto import for us typescript always does but sometimes it's iffy otherwise so let's say we now want to call this whatever it looks like it's going to do it for us amazing so now we've got whatever loaded look at that it loaded the new component just kept the state and everything it's so cool and so why this is really useful is you know when imagine that you're like filling out a form uh that you've built that's a controlled form or anything else like that and you're trying to you know test different stuff out but you want to keep it in the same state maybe it takes like several steps to get to a particular state and then you want to make a change and see that that's where this is really going to pay off but let me show you something that's really important so in this whatever i have a state and set state as well okay and all i'm doing is just making it to where when you click the button it says button clicked it's very dumb it's pointless but the purpose is to show that okay so you uh just to show you again you already know that if i change this you know the state is going to stay the same we already know that that's cool but what if i like remove some stuff from the dom here ooh what happened there well we lost all our state that's because uh the parent has to re-render and when the parent has to re-render uh all his children are gonna re-render unless you know you're you're setting them up in a different way but let's not get into that so in this case uh what i want to show is that if we go to uh let's say whatever here i'm to click this button i'm going to click this button and then i'm going to delete the h1 and notice that it did do that actually you know it's a better example let's do this so uh with this button clicked i'm going to delete the button and now notice the state kept it saying button clicked even though i deleted that button so it kept the state for itself and it also didn't re-render this other component because they're sibling components and i'll do the same thing for recipes we've got our state up here and then if i go down here and let's just say i you know i wipe out these buttons or or whatnot i'll still have all of these bullets here and i'll still have this state here and that's really cool so these two are siblings they're not affecting each other and that that's just showing uh some of the power of fast refresh so again this is really awesome i'm i'm so excited for this uh it's fantastic i want to show you one more feature real quick of this that i learned while i was doing this so you can you can at this pragma to the top here that says refresh at refresh reset so this this comment in this style with an at here is known as a pragma we're not going to get into that but this is a way to add a little custom functionality to just this file so what's going to happen here is now when i click this and i change some text and save notice that it wiped the state even though it normally wouldn't so why that is is this little command here is like maybe uh we're a little bit too hot module reloading for you and uh you really do want to wipe state every single change well you can just add that little pragma that directive at the top there and that'll change that now that i wiped it out just to show you again you know i've changed the state and i add something here and the state stays the same but this thing uploaded for it so you actually have this option to opt in to kind of force a reload on a file by file basis yeah they've thought of everything so uh that concludes a quick little demo of react refresh it's very exciting and i'm glad to have it working in webpack five there's just one last step that we need to do uh in order to keep this production ready i'm going to show you that right now so if i do npm run build i'm actually going to get into an error unfortunately and it says react refresh babel transform should only be enabled in development environment so i just wanted to get that working to show you that but now what we need to do and i'm going to make this full screen to make this a little bit easier to read again it's breathing room there is we need to change our babel config and our webpack config to only enable this when we're in development and the easiest way that i've found to do that is i this is why we used a babel config in the first place actually for stuff like this i'm going to set plugins i'm going to make it equal to an empty array and then here what we'll do is we will set this let's cut that out real quick to just plugins and then what we want to do is do a check and say if process dot env dot node env is not it's not equal to production so if we're in development we're going to do plugins dot push and then we'll do react refresh label so this will say uh you know by default it's an empty array but if we aren't in production then we'll add this to it um you might have a better way uh you know feel free to leave it in the comments if you thought of something smarter but this works for me now webpack config we need to do kind of the same thing here and because we've already set up this this if statement this way it's actually not going to be too big of a deal so what we're going to do is we're going to say const plugins equals but a little bit different on this one we're going to go down here to this plugins array and we're going to we're going to cut this whole thing move it to the top here so we're going to start with all of the plugins here okay that we have by default except for this one what we can do is we can come down here and say else because here we're checking if node environment is production and we don't want that there but we could say plugins dot push if it's not production i want to push and then we'll just snip this little line out here and i guess we don't want the comma but i'll get rid of it later i guess cut that there there you go and then what we need to do now is go down to plugins and say plugins plugins plugins something go back up like we're not formatting this comma yes it's always something okay all right there you go you've got your build working um the build's working and then let's also make sure that we still have fast refresh because we don't want to lose that so we'll go back to here uh bring up our browser and then let's say uh we're back to this world again so then we go to app and let's just make sure that with this man wait let's reload let's just make sure and then go to here blah blah yeah there we go okay so that sums that up i'm just gonna really quickly recap over this one uh the well let's do it this way we'll finalize this whole thing here right so we started here with this babel config we needed to set the setup we just did so that we can kind of dynamically add the plugins we know what's going on there and then in our package json we've added these two packages yes we know that we have our webpack config and uh this is where i'll kind of just really briefly go back over this again in case you notice this so what we're doing is we're moving the plugins up to the top and we're saying these are going to be our default plugins that we're going to have no matter what and then if we're in production we don't do anything but then else which means we're in anything other than production it's probably going to be development then we're going to push this onto the stack for just development so that doesn't break the build in production and we need to add this entry point for react refresh to work uh because it wasn't auto looking for that it wasn't inferring the default from webpack config and then finally we just call those plugins down here so we move on to this we just made a new component for demo purposes nothing really too much crazy to see there and uh yeah we can throw that in there why not and then we'll say add react refresh for development fast refresh whatever you want to call it now this is where it's pretty cool and that's why i wanted to take you through this last step so when i get push origin oops main let's go back to the browser here and see what happens get over there i'm going to refresh i don't know if this auto loads maybe it does eventually you'll see that we already have a production build building because we pushed up and that's part of that continuous integration that we got from setting up with netify so if we were to refresh this when this is done uh you know it'll change with our new content changes and then that's really sweet see this is already done yeah that's so fast it's amazing we'll reload here and boom we've got our new stuff all right ooh i almost forgot a little gotcha here i've got one last thing that we need to take care of for our react refresh setup and that's that when you run npm run build dev you're going to get an error here and i got stuck on this error for a bit as well but it's really just because um when i for this little fix that i've made it says process env node env equal to production so we're checking our are we in the production environment and that's when we're going to set that but else so in any other situation we're going to do a react refresh webpack plug-in but we actually only want that when we're doing the webpack dev server and live or loading and we don't want that on build dev so it's going to try to look for the webpack plug-in down here this is what i've deduced that it comes from is that uh now in the newer webpack when you just set hot to true it automatically loads in the webpack hot reloading plugin which it didn't used to do and this is relying on that and it's not finding it so all we need to do here i just have a quick silly little fix here what i did you can do this however you like but on my build debt or my webpack serve actually i want to set this another environment variable and you can make any one up you want and i'm just going to set it to true it could be any property that you could check for or whatever and then when i come back here to webpack config instead of doing this else we can just do another if so let's put that on a new line and we'll say if process dot env dot and then we'll do serve is equal and you can name that whatever you want uh and then let's just set that well actually you know what since it since it's anything if we want to set to anything let's just say is that set at all and if it is um then we will go ahead and push this react refresh webpack plugin on there let's see if that works for us build dev okay and that looks like it's all working we'll just really fast check our main js output oops and uh there we go we have it all here and building in the dev environment and then if we do npm run build you know we always want to check our other ones just to make sure that we didn't mess with them at all that's going to work as well it's going to be all minified and all that good stuff and then finally if we do npm start oh and can i click this control click now nice okay well that's new in windows terminal i've been wanting that for so long all right sweet well uh now we can see it loading and our state's still working fine and to make a quick check and then we'll just go into app jsx here and then i'll just change the text here and make sure that it live reloaded or hot reloaded sorry without changing the state or anything like that so everything's still looking good and that's all there was to that now that might not be the most elegant way to deal with this problem but it works for me right now and we're in this kind of experimental mode that you might not even be in with this plug-in hopefully it'll be a little more polished in the near future but for now i just wanted to show that because i had to do a little bit of troubleshooting to figure that out hopefully you can skip that whole phase and this will just work for you so that is going to wrap up this whole video and i know that was a lot of stuff but hopefully you've got a good concept of how to put all these really important pieces together to create a whole webpack project and the whole purpose for me is that at this point i know that i probably didn't cover every little flavor and every little plug-in that anyone could want i can't really do that but it's at a pretty good spot right now where it's extendable you've got the gist of like what it's like to continually add loaders and plug-ins and all of the new cool webpack 5 fable 7 features and all that good stuff plus we got the latest react refresh working and so now it should be in a really good spot uh as a starter project or whatever for you to extend it to whatever your needs might be so yeah if you stuck it out all the way through this congratulations that's a ton of distilled information to take in but hopefully you're a lot wiser for it and ready to move on with your own webpack projects so thanks for watching and i hope to see you in the next video that's probably pretty bright for you isn't it maybe
Info
Channel: Swashbuckling with Code
Views: 31,671
Rating: 4.9796066 out of 5
Keywords:
Id: TOb1c39m64A
Channel Id: undefined
Length: 118min 59sec (7139 seconds)
Published: Mon Feb 01 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.