Coding

Learn Webpack – Full Tutorial for Beginners

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