Understanding the Complexity of Modern Web Dev Stack (Webpack, Babel, TypeScript, React)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
modern web development is notoriously complicated when i first picked this stuff up i found it very difficult to understand all of the moving parts including things like babel typescript webpack view and react and so on and so forth so what we're going to do in this video is try and cover off all these different tools and how they work by starting off with the most simple application possible and slowly adding each of these tools seeing what problems they solve and what problems they might introduce so let me set the scene for you it's around the early 2000s websites are still relatively simple they're mostly static content maybe with a bit of javascript and that's what we see over here on the left we have this good old programmer having a great old time he wrote his code and then he just uploaded it to a server and everything was ready to go and he has this nice counting website skip forward 15 or 20 years and we have a slightly less happy programmer doing exactly the same thing building exactly the same application but he has to use babel and typescript and webpack and all these other frameworks so let's kind of take a bit of a walk down memory lane and see how all of this stuff has come together let's get started right now so the first thing we're going to need to do is create an index html i've already started off one nice and simple we're just going to remove these script tags and start again so the first thing we need to do is create some elements we're going to start off with a button and this one is just going to show increment all we need to do now is create one more element that's going to be a h1 tag and we're going to start with a count of zero the next thing we're going to do is add some interactivity and of course we're going to do that with a script tag the first thing we're going to need is a function that increments count let's just go ahead and call that one ink we're going to say count is plus equal to one and then we're going to create a new variable count is equal to 0. of course we have to use es5 javascript including things like var and we can't use arrow functions because it's still the early 2000s and people have really old browsers anyway the final thing we need to do is increment this number so let's go ahead and give it an id i'm just going to call it h1 for now and we need to make sure we increment that by saying document.getelementbyid we're going to go ahead and grab our element and then we're just going to increment that by saying text content is equal to count let's go ahead and give this one a try so we head back to our browser and refresh the page we can see nothing is happening because i opened the wrong file let's go ahead and open index html and we have this this is our html file not really what i was hoping for let's go ahead and try again one more time and we have a bit of a problem why is it not rendering the correct content i'm actually doing view source that's another very old school thing to do what i really want is just to open the file and you can see now everything is not working it looks like i've made a mistake what we forgot to do is add our event listener so let's go ahead and say on click and just call the increment function and this is all going to work apparently it's not going to work because i didn't refresh the page and now it is so of course we haven't got hot reload it is still the early 2000s i kind of forgot about that we have to refresh the page manually and everything is working correctly so far so good but your application is going to inevitably get bigger and it's not very scalable to put all your code inside of the script tag what we're going to do is move it to a separate file by creating a new file called index.js this is going to be a fairly simple migration i'm just going to copy and paste that one over and that's all we need to do finally we need to import this or not really import we need to include it by saying source and just say index.js if we did everything correctly we can see the website is still working so far so good as websites get bigger it's obviously not very scalable to put all your tags inside a single body as well so what we're going to do is move these out and there's not a great way to do this other than moving this from html to javascript so that is exactly what we're going to do by creating a new file or actually using the existing file called index.js and moving these over there we are going to need to need to write a little bit of javascript just to save a bit of time i prepared a utils file and this contains a single function called create element it's going to take a type for example a div an id some content and some events all we're going to do is create the create the element going to assign some values to it we're going to loop over these using object.entries this is some very new javascript so we're going to have to find some way to make it work in old browsers add the event listener append the element and then return the element so let's go ahead and see if we can get this working the first thing we need to do is create our button i'm going to say var and we're going to make a new button here and this is just going to be equal to create element which is going to be globally available it's going to be a button type it's not going to have an id it is going to have some text let's just say increment for now and it's going to have some events as well this one's going to have a single event of click and what that's going to do with an arrow function by the way so we don't need to find a solution to that arrow function problem is increment the value by saying ink finally we need to create one more element which is going to be our h1 we're going to use var again for h1 it's going to be a create element of h1 with an id of h1 and the content is just going to be r0 now that we have that everything should hopefully be working let's go ahead and try it out if we head back to index html we have our index tag already all we need to do is include the utils file as well and everything should work as expected if we head back to our browser now and we did everything correctly it is all still working we do have to be quite conscious of these two sometimes the order of scripts is going to make a big difference and that's a problem we're going to solve later on using a tool called webpack before we use webpack what we need to do is find a solution to our es5 es6 problem i'm using an arrow function here which is not going to be valid in es5 javascript the same javascript everyone is using in the world because we have old browsers because it's the early 2000s still and we have another problem in utils as well the problem here is we're using object.entries and this is not valid es6 or es5 javascript we need to find some way to make this into valid es5 javascript and that is where our first tool comes into play babel babel is a javascript to javascript compiler it's going to compile javascript to maybe an older dialect of javascript for example es6 to es5 so let's go ahead and see how that one works the first thing i'm going to do is i already installed everything so i'm just going to say yarn babble and we're going to transpile index.js into es5 javascript we're going to pass in a preset and that's just going to be a preset environment of javascript in this case i'm going to use a very specific one which is going to be at babel preset env and i believe this is the correct syntax let's give it a try and see what happens and you can see that did actually kind of work what it's done is add all of these semicolons for us and it's also changed everything from const to var finally we haven't got our arrow function anymore we now have the function so this is going to be valid es by javascript everything is working correctly so far the next thing we need to do is go ahead and actually put that into a file so that's exactly what i'm going to do by just go and copy and pasting it we're going to create a new file called es5.js just to make sure we remember and this is going to work in any old browser finally what we're going to do is transpire one more file and that's going to be our utils file and this one is going to be a whole lot more messy let's go ahead and give it a try and see what happens so this has generated a very huge piece of code you can see we have this iterable to array limit function we have arrayed to array like function we have unsupported iterable array and a whole bunch of extra code the reason this is here is because of one specific function object.entries this is not valid traditionally so what they've done is actually polyfilled this they've created a bunch of other functions to support this so we're going to be able to use the same javascript syntax when we write our code but it's going to transpile to something very different which is where we end up with all of this extra code that's kind of a necessary evil if you want to use new javascript in old browsers anyway with that in mind what we're going to do is pipe that one into utils.es5.js just to make sure we can actually use it let's go ahead and just delete this extra code there's two extra lines here and make sure this is still working by heading to index html and updating our code all we need to do is say es5.js in here and if we did everything correctly uh we're going to have an error apparently see if we can fix that one up it says identify i started with immediately after numeric i have no idea what that means i have this extra code down the bottom let's just go ahead and quickly fix that one up come down here and delete that code let's give it one more try heading back to our browser and everything is still working but now we're confident that it's going to work in old browsers because of babble so we've definitely made an improvement the next part of this puzzle is going to be something called webpack so let's see how that one works we currently have another problem and that's we're going to have all of these strip tags and it's very hard to share data other than making everything global which is obviously not a very good idea what would be really nice is if we could compile these into one single script so let's go ahead and do that i've already installed this one but i'm going to create a new file called webpack.config.js and this is something known as a bundler it's going to take all of your files and bundle them together into one single file and it's also going to give us es modules so we can import input import and export variables so we don't end up with this mess of all these global variables now that i've created this webpack config we're going to do a export in here module.exports and just set up some very basic configuration i'm going to have an entry which is where everything starts in this case index.js and this is all i'm going to do for now let's go ahead and save it off and give this one a try i'm going to say yarn webpack passing my config file and that's going to when pack config js and run this one and see what happens i'm actually going to set this one to mode development just so you can see what's going on it's going to make the code a tiny bit more readable and if we do an ls i have a new directory dist if we go into dist inside of main.js which is what it created we have this big file and you can see it's actually put both of our files in here we have index.js and here's all of our code on one line so it's kind of working i suppose if we keep on going down we can see that's the end we haven't got our util file here what we need to do is import and export everything at the moment we have this create element function and we have no way to actually access this one what we're going to do is head back to index.js and update this one so we'll close this one off head back to index.js and i'm going to import my function we're going to jump up here and say import create element that's going to come from utils.js now that we have that we can head back to utils.js and make sure we're exporting that one and now we have a big improvement instead of having lots of small unrelated files we have a module system and everything can import and export each other we don't need to think about the order we include the script tags in our html file so this is the role of webpack now that we've seen that let's go ahead and give it one more try i'm going to run yarn webpack and it's going to generate a new output and it's now bundling both index and utils we need both of those files for our application if we head into main we can see it's changed a little bit more now we have one file here this is index.js and if we scroll down a little bit more we have another file called utils and that's going to have our utils function down here we do have a problem though if we come in here we can see we actually have the arrow function again so although we have one single file it's not going to work in old browsers this is because webpack and babel are not talking to each other we need to make sure we're using both these tools together and this is where things start to get complex you can imagine how much more complex this is going to get we need to make sure webpack can communicate with all these different tools and bundle everything together correctly let's go ahead and do that so the first thing we need to do is come over to our webpack file and we're going to use something called a loader we're going to tell webpack to interpret this in a specific way and use something called babel loader to do the same transformation we did with babel but this time we're going to do it as part of our webpack pipeline this means i need to create a new key called module and inside of here we're going to have something called rules i believe inside of here we need to check each of the files and then tell it what to do so in this case we're going to have a check i think we're going to say type and we're passing what type of file we'd like to check against let's go ahead i think it's actually test so we're going to test against a regular expression we're going to look for dot js files and then we're going to say use and we're going to use something called babel loader let's go ahead and see if i remember all of the syntax correctly it's a very high chance i've made a mistake here but i'm just going to give it a try anyway but go ahead and save this one off and close it see what happens if we run yarn webpack config again we're going to get another file and with a bit of luck we're going to have es5 syntax instead of ear syntax 6 syntax if we jump inside of here we can see that is actually not the case i'm still getting the arrow function down here so what we need to do is figure out what i've done wrong in my webpack configuration i'm going to go ahead and check that really quickly this all looks completely fine to me i think this is incorrect it should not be test it should be something else but i don't really remember off the top of my head what it is and this is one of the problems with the modern javascript stack it's really really complicated what i'm going to do instead is just go ahead and check my other branch which has all the correct information it's going to commit this one off save it and just say save check out master and see what the original branch actually does test is actually correct and so is use so i think the problem is my regular expression is not correct i'm going to go ahead and try and fix that one up right now i'm going to head back to my other branch which is going to be called main a little bit embarrassing that i forgot that but who can blame me with all the complexity of this and try and use my new test file so what i needed to do i think was just make sure i'm checking against the correct things possibly ending in dot js let's go ahead now and give this one more try and see what happens if i do a yarn webpack and pass in the configuration we should hopefully have something a bit better now i'm still getting the same problem because i didn't run the correct command and now with a bit of luck we're going to have something a bit different we didn't pass in our mode again i just like to be able to read this so i'm going to pass in development now if we head in here we're still not getting any luck everything is still es5 javascript and the problem here is we're not telling it which conf configuration to use we're currently using babel but we haven't got the correct configuration so what i'm going to do is create a new file called babble.config.js and inside of here we're going to go ahead and do a module.exports and we're going to tell it to use that preset invert and that we used before so we can just say presets pass in an array and this one is going to be at babel preset end with a bit of luck this is now going to transpile correctly to es5 javascript let's go ahead and give it a try so this should hopefully give us something a bit better if we head into this dot main we can see this is now working correctly we haven't got any arrow functions inside of our code down here anymore we have function click instead so we managed to transpile to es5 javascript while using babel ironically the webpack code is using an arrow function up here so we are going to have the same problem it turns out what you need to do in your webpack config is add another one in here called target es5 and this is going to make sure webpack converts itself into es5 as well if we go ahead and run this again one more time we are going to get the correct output here and what's happening is we now have got rid of the arrow function we have now got a regular function instead with a bit of luck this is actually going to work correctly so if i head back to index html and update this one we now have a single file so we solve the problem of having multiple files we just have one now everything is in the same place just to make sure everything is still working let's give it a try we are getting an error still it says import declarations may only appear at the top of a module let's go to index.js we're actually importing the wrong file here it should be main.js that comes from dist and this should hopefully not work and everything is still working but it's a whole lot more powerful and also a whole lot more complicated not sure if this is a good or a bad thing it is what it is we've now seen two parts of the stack babble for compiling javascript to other javascript and webpack for bundling everything together so far everything is good and this is kind of what we did for a few years eventually we realized that it was difficult to write applications like this or at least some people thought so and they decided we needed a better way to do things so let's go ahead and see what that might be they decided we needed something called react so let's go ahead and check that one out if we head over to index.js this is our entire application right now what we're going to do is convert this to use react so the first thing we're going to do is import a few things let's go ahead and grab react from react and we're also going to grab react dom from react dom now you might expect me to start writing some jsx but that is not going to be the case at all this is not how react started it was not always using jsx and we're going to see how that works without jsx right now so the first thing we're going to do is create a new our new function i'm going to call this one app you would have traditionally traditionally used something like react.create class but we're going to do it using the new syntax let's go ahead and create a new count and a set count we're going to use a hook which is for state and we're no longer doing imperative updates we're using react to update automatically using their reactivity we're going to say react.use state inside of here and set that one to be 0 by default and then we're going to return something we don't have jsx right now what we're going to do is say react.createelement and create a new element i'm going to pass in a div here for my first one and that's going to have an array of children we're not going to have any props so let's go ahead and pass an empty object here and the first thing we're going to go ahead and create is going to be our button going to have a button and this one is going to have props the prop is going to be on click and when this one is called it's going to just go ahead and say set count and increment count by one now that we have that we're going to need some content i'm going to say increment and this is a pretty difficult to read and that is kind of the idea or behind jsx which we're going to see in just a moment anyway now that we have that one we're going to have one more element so let's go ahead and copy paste this this one is going to be our count it's going to be a h1 and inside of here we're going to have our count let's just go ahead and render our count down here and we're not going to have any props so i'm going to delete that one now that we have this we have to mount our application so we're going to say react dom dot render and render out our application the first argument is going to be i believe the application so let's go ahead and pass in our app and that means you have to do react.createelement again a very convoluted passing an app and the second one is going to be where to mount it so i'm going to say document.getelementbyid and grab my element by id in this case i'm going to call it let's say app we need to create that one as well so let's head over to index html and create it let's go ahead and create that one i'm going to call it div id with app go ahead and instantiate it finally let's give this one a try with a bit of luck this is actually all going to work so what we're going to do is we're using react we're not using jsx and we're going to bundle this all up and with a bit of luck it's going to work things never seem to work first try those so i'll be surprised if it did let's go ahead and compile this you can see that was a lot slower because react is a very big library if we jump into dist main this is where things start to go kind of downhill it is no longer possible to read the output of webpack this is just impossible it's this huge mess and if there is a bug in here then good luck finding it anyway let's go ahead and try this out and see what happens we can see everything is still rendering and somewhat surprisingly everything is still actually working correctly i didn't make any mistakes we do have this error or this warning i'm going to ignore that one for now we're now doing exactly the same thing with a whole lot more complexity under the hood so now we've seen another part of the stack we've seen babble we've seen webpack and we have seen react but things are still not complicated enough the next thing people realized was it's very hard to write this syntax it's kind of difficult to read it's so javascripting now let's head back the other direction to html and they did that by using something called jsx and that is what we're going to do now to start off i'm going to go ahead and move my file actually i'm going to copy it just in case index.js to index.jsx now and i'm going to remove the original file finally let's go into here and convert this one to jsx and this is going to be fairly simple we're just going to have a div in here and that's going to be a button with an on click listener and as you can imagine this is going to do it's just going to call that event so we're just going to say set count count plus 1. now that we have that we just need to go ahead and render let's say increment down here and then we're going to close off our button this should be a button not a div and then we're going to create our final one which is going to be that h1 and things are now heading back the opposite direction we started off with all html then we moved all the way to javascript now we're sort of heading back to html a little bit ironic but they say things come in cycles anyway with a bit of luck this is now going to work this is a fragment so we use the very awkward fragment syntax you have to have a root and if that's going to be a fragment there's nothing nothing you can do about that let's save it off and see if i didn't make any mistakes if we head back here this is still working because we didn't even compile webpack let's go ahead and try and compile webpack and we are of course going to get an error here because we changed the name about our input this should now be jsx and we're now going to check against jsx files as well and see what happens let's go ahead and try again one more time and of course this is going to fail as well we're attempting to compile javascript and this is certainly not javascript we need an extra preset what i'm going to do is update babel config and we're going to pass in a different preset we now have two presets we have es5 and we're also going to have react so things are getting more and more complex more and more layers of complexity welcome to modern web development anyway that did indeed compile and we could go and look at the main.js file but there's just no point this thing is completely unreadable at this point so let's just give up on that and hope for the best if we head back to our browser everything is still working our area is gone because jsx does some magic under the hood and we are definitely are still making the exact same app just with more and more uh layers of complexity anyway this was kind of where we were for a few years everyone was somewhat happy with how things were working or at least they weren't unhappy but then we realized javascript is not that great because there are no types what if we had types and that is where the final part of this puzzle comes in typescript and by extension tsx so we're now going to have typed jsx which is a derivative of javascript kind of let's see how that one might work the first thing we need to do is change the name of the file again so it's now going to become index.tsx and we're going to go ahead and update this one now as well we haven't got many types here but we do have one this one is going to be a number via this generic now that we have that let's go ahead and try and compile this again we're going to have to update our webpack configuration again and this one is now going to become tsx let's go ahead and try this out and see what happens just to save a bit of time i'm going to run yarn webpack in watch mode and that's going to give me exactly the same thing but it's going to do it automatically every time i save up off my file we're going to put this one mode in let's just say development for now and then we're going to go ahead and say watch and this is going to run automatically this is actually going to fail we have an error see if we can figure it out this is the wrong name it should be tsx if we try again we're going to get uh apparently not going to get an error which is kind of surprising let's go ahead and try this out you can see this is completely broken it says number is not defined and this does make perfect sense if we head back to our file we have this generic type here and this is not part of javascript we need to use a typescript compiler as well so now we have two compilers typescript and babel what this means is we need to update our webpack configuration we're going to have an additional way to compile we're going to use another loader that's going to be called ts loader so we're going to convert the typescript to javascript and then javascript to es5 javascript let's go ahead and give this one a try with a bit of luck this is going to work it is even slower now but that it is what it is we have a different error now which is to do with react not being defined again this is very confusing and very difficult to debug unless you really know what's going on it turns out you need to either configure typescript or you can just go ahead and say input all as and this is going to fix our problem finally everything is working again and now we're in a pretty good place at least in terms of the modern stack we've seen babel for compiling we've seen typestrip for compiling we've seen webpack for bundling and we've seen react for the actual ui layer we have managed to merge both our javascript and our html into a single file you might think this is the end you're sorely mistaken what if we go ahead and merge some style in here as well and it turns out that is possible i'm going to create a new file called index.css and we're going to give this one a color of blue of course what you could do is just import this to index html like any sane person would do but we're not saying we are insane we are modern web developers so of course we're going to import everything into exactly the same file inside of here i'd like to import my css into my javascript file or my typescript file or my typescript sx file i suppose you would call it at this point anyway this means we're going to need another loader so let's go ahead and create one more extra loader and this is going to be the last one that we create we're going to need two things inside of here we are going to need css loader to load the css and we're also going to need something called style loader to make it inject to the document let's go ahead and finally give this one a try and see what happens hopefully we're not going to get any errors we actually are and this is another kind of symptom of modern web development it is incredibly confusing and difficult to figure out what the heck is actually going on here i think these might be in the wrong order so i'm going to go ahead and try them in the opposite order this is generally what i do nowadays if i don't know what's going on i just try things randomly until they work and usually i stumble across the correct solution eventually let's give this one a try as well and see what happens and that is successfully building finally if we come back here everything is working correctly the the number is now blue so you can see we've kind of evolved and sort of taken a few steps backwards as well depending who you ask we started off with code now we have code where we transpile down to old javascript from typescript we bundle it with webpack we're using react and of course we're also bundling some styles and who knows what else inside of there eventually we get our giant bundle we ship it to the browser and we build exactly the same thing people have been building for the last 15 or 20 years we just did it it cost us a lot more money and a lot more time and we just increase the complexity significantly anyway i hope this gave you a good idea of how the tools work together it was a bit cynical but there are a lot of great things about these tools as well we have things like hot reload we have lots of different techniques to be able to use modern javascript in old browsers so it's not all terrible i'm actually pretty happy with the way the stack is right now as long as you don't have to configure it everything is pretty nice to work with i hope this gave you a bit of an idea of how things fit together and how all the different tools are interacting with each other and i'll see you in the next video
Info
Channel: Lachlan Miller
Views: 989
Rating: 5 out of 5
Keywords:
Id: QliwSwWHJoQ
Channel Id: undefined
Length: 26min 42sec (1602 seconds)
Published: Thu Apr 08 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.