This course has been updated! We now recommend you take the Complete Intro to React, v8 course.
Transcript from the "Configuring webpack" Lesson
[00:00:00]
>> Brian Holt: We're gonna go ahead and start with webpack. So let's go ahead and first make it necessary for us to have webpack. So here in klineapp.jsx rather then having React look like this up here, we're gonna say, import React from 'react'. And we're gonna say import render from 'react-dom'.
[00:00:34]
>> Brian Holt: Okay, so these are ES6 modules, this is what they look like now. For those of who that are coming from a node background or a common JS background, this is the same as const React = require('react').
>> Brian Holt: But, we are not doing this anymore. This is the old way of doing it.
[00:00:58] Import React from 'react', this is the new way of doing it. You might ask yourself, why are we doing it this way? Why didn't we just stick to Require? Because, everything already supported Require. Well if you look at what just was there, this is dynamic, right? We're feeding React into a function that's gonna bring it in, therefore we could say require x, right?
[00:01:20] And x = 'react', so this can be dynamic. Which is cool. But to be honest with you, most of us were not using the dynamic functionality of importing modules. Some of us were. Someone's gonna point that out to me. But most of us were just using it statically, right?
[00:01:38] Which is exactly like this. You can't say import React from x, that's invalid, right? It's always going to be from that. So in light of this, if we do static modules as suppose to dynamic modules, this forges some really cool things. That for example, we can have webpack go through all of our code and only include the things that are actually being included.
[00:02:05]
>> Brian Holt: So an example of that would be, let's say I had a module that explore default or I'll say export,
>> Brian Holt: const x = 5 and I have another that says report const y = 10, right? So let's say I had a file that did this, that I exported these two different constants, right?
[00:02:32] And in another file, I would say import, so different file.
>> Brian Holt: Import x from like I'm in clined app right now but it could be from MyModule, right?
>> Brian Holt: This is my module.
>> Brian Holt: What's cool about this is I'm only including x, right, and I'm not including y.
[00:03:04] Webpack is smart enough to say, now because of static modules why is it never imported, I'm not going to include it. Now this is often referred to as tree shaking, right? That's the common terminology for this which is a total misnomer, right? Cuz tree-shaking has the idea like, you're gonna go through and shake all the dead things off.
[00:03:26] It sounds like dead code elimination, which is not actually quite true. It's actually live code inclusion. [LAUGH]. So it's actually going to only include things that could possibly be reached. As opposed to dead code elimination, it's going to go through your code and remove things that could not be run.
[00:03:43] Largely you're gonna end up at similar situations. But let's be accurate here, right? So that's why we went with this new module system, is it can be statically analyzed by our tools. And we can start pruning things off that don't need to go down the wire, right? That's really important to us cuz we're trying to constantly get things done in terms of file size.
[00:04:04] So notice that I'm saying includ only render from react-dom. Now I have no idea how react-dom is actually structured. But ideally, if render is not importing other things, and react-dom was built with this static analysis in mind, we could only include the render function and we could leave everything else behind.
[00:04:27] I don't know if that actually happens or not, but it's just a good idea to only include the things that you need. So just in case they built in such a way or maybe in the future it gets built in such a way that you're only including code that could possibly be run.
[00:04:40] So that's what these curly braces mean, it means I'm only including this particular piece. So down here instead of saying ReactDOM.render I'm actually just gonna say render, right? Cuz these two reference to each other, render and render. That makes sense? Now, notice I don't have curly braces around React.
[00:05:02] I'm including the entire package here. So if you remember here, I had export, cont x = 5, right?
>> Brian Holt: So if I say export default 5, right? That's what you're getting here. That's the default export.
>> Speaker 2: If you mixed in a require in there, if you did have a dynamic module that was being loaded, would webpack just skip over it then?
[00:05:32]
>> Brian Holt: I think the answer to that question is it would just compile to be the same thing. I think it actually would work. It's not valid, right? But I think it would still work with webpack.
>> Brian Holt: The real answer to that question is you still can do dynamic imports.
[00:05:50] It's just done differently now.
>> Brian Holt: We're gonna talk about it at the end of the third day, but there's a thing called, import as a function, right? And this is going to be how we do dynamic imports now, right? And then you can say promise, .then(React) right and then you can start working with React inside of that promise body.
[00:06:20] So that's also asynchronous.
>> Brian Holt: So semantically it's a bit different but this is ultimately gonna be better for us. It's gonna be better for the web. Okay, so, now this doesn't work. [LAUGH] We broke it. Because this has to be compiled now. Because right now, well, actually, Chrome does support a little bit of ES6 modules native to the browser, but we're not going to be doing that today.
[00:06:53] So we need to run this through webpack now, so that webpack can go out and grab React, it can go out and grab react-dom, compile them together and send down one file.
>> Brian Holt: So,
>> Brian Holt: What we're gonna do here
>> Brian Holt: Is, there it is.
>> Brian Holt: We're gonna go to the command line.
[00:07:21] And we're gonna say,
>> Brian Holt: First of all, you're gonna have to do either a yarn global add or an npm install--global.
>> Brian Holt: If you're getting sick of this, there's also kind of a little cheat that you can do here. You can also say ./node_modules/.bin/webpack, it should work for all of you if you've done the yarn installs.
[00:07:48] So, inside of bin, it's gonna be all the different things that are being included into our project. So we could call eslint from there. We could call flow from there, prettier, all these different things. So if you want to, you can do that as well, or you can just install it globally.
[00:08:06] That's kind of up to you. I have installed globally, so I'm just going to do it that way. Maybe I don't. So I'm gonna do it that way. Node modules.bin/webpack. Then the entry file is going to be client, or it's gonna be jsx, ClientApp.jsx. And then I'm gonna have it output to public/bundle.js.
[00:08:33] So, you can see now, it took in this file, Clientapp dot jsx, and it output bundle.js. So now, if you go into pubic you should see a file called bundle.js,
>> Brian Holt: And you can see that it has all of this stuff in there.
>> Brian Holt: Did I not save this?
[00:09:08] I did not save it, okay. This should be a lot bigger now, because it's going to include, run it again.
>> Brian Holt: There you go, okay. Yours should look something like that, right? Basically it's saying I needed to include all of this stuff, right? Cuz this is all the stuff coming from React.
[00:09:33] And I outputted a bundle that is 739 kilobytes. Seems reasonable, doesn't it? It's not, it's not reasonable at all. But you have to keep in mind, this is un-minified, this is un-g zipped, and this is the development build, right? So we're building specifically now for our purposes. This is gonna be cone that's easier to read, so you can actually open up the bundle and read it.
[00:09:56] And it's going to be the version of React that has all the developer warnings and all that kind of stuff available.
>> Brian Holt: So when we build this for production, it's going to be much smaller, right? Because it's gonna minified. It's gonna be gzipped. It's gonna be tree shook.
[00:10:11] It's gonna be all those different things.
>> Brian Holt: Okay, so now if we go to index.html and we have the script right here. We're gonna say source equals public/bundle.js, right? And now, we don't have to include these two script tags up here either, right? Cuz they already been included with our bundle.
[00:10:43] So this is one of the nice parts about webpack. Cuz every time I include a module, I don't have to go and add another script tag. It's just going to be always included in there in that bundle.
>> Brian Holt: So I should be able now to go to this.
[00:11:04] And I can refresh, and it still works, right? Everything's still being included.
>> Brian Holt: And you can see there it's only including bundle. Which if you look at how big it is, it's quite large
>> Brian Holt: You can see it's huge.
>> Brian Holt: I mean look at that, look on the side there.
[00:11:32] It's just astronomically huge. But this is literally the entire library for React unminified with all of the development helpers.
>> Brian Holt: Any questions about webpack?
>> Speaker 3: Could you go back to the client again?
>> Brian Holt: Yeah.
>> Speaker 3: How does it know how to do that without any webpack config file?
[00:12:02]
>> Brian Holt: Well we're just using all the default setttings.
>> Speaker 3: And wetpack already has that out of the box?
>> Brian Holt: Yeah, it's actually, people like to think that wetpack is a big complicated beast for sure. It doesn't have to be a big complicated beast. The only thing that bare minimum that it requires, it requires an entry point, which we gave it, Clientapp, and requires an exit point.
[00:12:25] Which is bundle.js. Everything else, we can just rely on webpack to take care of. Now don't get me wrong, we're about to make a big ass config file, right? Because we don't want the default build, but by in itself this works as is. Webpack can be configured through the CLI.
[00:12:47] I guess that's what I'm trying to get at here.