
Lesson Description
The "React Server Components from Scratch" Lesson is part of the full, Intermediate React, v6 course featured in this preview video. Here's what you'd learn in this lesson:
Brian guides walks through through setting up an RSC project with Webpack, covering essential packages and configurations. He demonstrates how to configure Webpack, set up Babel, and structure the index.html file.
Transcript from the "React Server Components from Scratch" Lesson
[00:00:00]
>> Brian Holt: We are gonna write some RSCs we can make building up to this moment and this is definitely not gonna let you down. It's never gonna give you up, it's never gonna let you down.
>> [LAUGH].
>> Brian Holt: You weren't expecting to get rickrolled by React today, but here we are.
[00:00:18]
Okay, so, this is a lot to code by hand, but it's kind of like it's a lot of machinery to get everything working together so bear with me, but we'll get there together. Some of the stuff I'm gonna hand wave over a little bit, because it's just not super important to getting everything correct.
[00:00:39]
But we'll try and focus on the actual parts that's gonna make you better at doing React. So we are going to code a bare bones, just RSE,with like, nothing else around it. So there's gonna be no next, there's gonna be no framework on top of it. We are essentially, the framework look at me, or you are the framework, right?
[00:01:03]
So the first thing is I'm gonna have you do is you can see this has a lot of requirements, and so I did write out the entire npm install here if you want to, I'm going to invite you to not load all of this. So why don't you just come in here and copy our package.json, or you can copy this, both of those are fine.
[00:01:22]
And then we're gonna create a new project, and we're gonna put this in here, and then we'll run npm install, and then I'll go over the actual components we have here momentarily. So come in here, cancel the other server I'm gonna make another directory, and this is just going to call this one no framework.
[00:01:42]
Okay, and then I'm just gonna open this in code and we'll close this one and we're gonna close this one as well and we'll maximize that one. Okay, new file package.json, I paste that in there. So let's talk for just a hot moment about what's actually in here.
[00:02:07]
One, we are gonna be doing CommonJS for this, not ES modules. Again, it was just way simpler, this is one of those things, I went all the way and made everything in ES modules and really pretty and really nice. And I realized we're gonna spend an extra 25 minutes just getting all this stuff working, and nobody cares, right?
[00:02:25]
So we're cutting all that stuff out so that's why there's a shortcut here. And the other thing you'll notice that we're gonna be using webpack this time, whereas I normally recommend people to use Vite. Again, I went through the whole process of making it work with Vite, cuz you can port webpack plugins to work with Vite.
[00:02:43]
It's fairly straightforward process, but again, I was asking myself, nobody cares. Why are we doing this? So we're gonna be just using Webpack directly. And the reason for that is this little magic package here called react-server-dom-webpack. This is the actual magic package that's going to do all of the server components.
[00:03:02]
It basically enables a Node server to be RSC enabled. Then we have some Babel here, again, this is something normally Vite wraps around for you so you don't have to peer into the unending abyss of what Babel can do. And then we're on fastify again, just cuz I like fastify, but you could have definitely done this with Express, or something like that.
[00:03:26]
Where else is in here? Pino, this is just a logging library, we're gonna be doing some sqlite3. So that's what's in here, just that's our example of what you can do on a server. Css-loader, I have this doodle.css, it's just a kind of fun, hand drawn this is like we're doing note passing, right, so it was kind of on brand, I think that's it.
[00:03:48]
So as you can see, nobody wanted to write all the npm installs for this that's why we didn't do it together. That being said, please come in here and just say npm install and wait for everything. I guarantee you this gonna have some of those security problems, cuz it always does, it's a lot of packages.
[00:04:09]
Yeah, deprecated, all kind of stuff, zero vulnerabilities probably by the time that you watch this as a recorded video, there's gonna be 30, it's fine, nobody cares. Actually, somebody cares, specifically, I don't care, [LAUGH] not today. Okay, so that is all of the packages next, we are going to write our webpack.config.
[00:04:34]
We're gonna code it together feel free to copy and paste it for my notes, this is not the part that I'm most interested in you learning. But I still wanted to make you understand what's in it, cuz I think that's important.
>> Brian Holt: So, const path=require, again, this is the, CommonJS instead of the imports node path, okay?
[00:05:00]
And we're gonna say const HtmlWebpackPlugin.
>> Brian Holt: This is the one that's going to make our HTML shell, right? That we were doing like our index.html before we're gonna rely on Webpack to do that now. Require, html-webpack-plugin there we go and const ReactServerWebpackPlugin, this is the one that we were just talking about.
[00:05:34]
Require, so you need both sides of this, the react-server-dom, you need your bundle to be bundled correctly for RSCs. And then you need your server to run this as well. So it has two components so you have to say /plugin. Cuz essentially it has to go make stubs whereas this is a server component.
[00:05:58]
Reach out to the server for this, that's what this this is gonna do for our bundle. Okay, const mode, this is all kind of webpack stuff this was kind of a jog down memory lane for me, cuz I haven't actually used webpack directly. And it's been a while, right, I've been using Vite for the past probably two years, and then before probably three years, I was using Parcel.
[00:06:24]
Nothing wrong with it webpack's great, and it was hugely instrumental in the development of the community here. The other tools are just a bit more ergonomic, I think. So I'm just getting here, are we in development mode? That's really what this is all for, cuz you'll bundle it slightly differently.
[00:06:44]
>> Speaker 2: Hey Brian, just to head up you have a typo on line three.
>> Brian Holt: Three.
>> Speaker 2: Plug in the very last word.
>> Brian Holt: Plugin, now it's finish actually, yeah, just kidding, [LAUGH] thank you. So yeah, make sure you spell not the Finnish spelling, the American spelling or English or Australian or Canadian wherever you are.
[00:07:05]
Just don't add extra o's as English and Canadians are want to do. Config = we're gonna put in mode, which would be mode, mode, but you can just do mode like that. Entry, we are gonna do JSX because we're gonna have Babel installed here as we can. So entry is going to be ./src/Client.jsx, module is going to be this, and then we're gonna give it rules, okay?
[00:07:41]
And then basically, just gonna say, if it matches this pattern, run it through this loader, that's what rules are here. A bunch of stuff I had to look up again cuz it's been so long. Test you give it a good old friend or regex.jsx ?$/, so this is essentially saying this is a rejsx, I assume most of you know enough to fear them, I do.
[00:08:12]
This is just saying, look for anything that ends with jsx, that's what the dollar sign means, is ends with, and then the question mark is like the x may or may not be there. So anything ends with js or jsx will match this pattern.
>> Brian Holt: use, we'll do babel-loader, so anything that ends with this run through babel and exclude.
[00:08:35]
Don't run anything from node_modules, modules. Let's do the same thing for CSS, we're gonna say test if it ends with,
>> Brian Holt: /\.css$/, and then you could put i here as well. This is just case-insensitive. My notes don't have it, so I'll leave that one off. This one does, that's probably because I copied and pasted this from somewhere, but don't tell anyone.
[00:09:13]
Run this from through style-loader as well as css-loader. This is just basically anytime that I refer to a css module, please load that into my final destination there. Okay, that's all for that one, we have to do the resolve here. Is that down here? Yep, resolve, nope, not that, and that's fine.
[00:09:41]
Okay, so anytime that I don't specify the extensions, then assume it's either .js first, and if there's no .js file, assume it's a .jsx file, that's what that means. And then plugins,
>> Brian Holt: Yep, so here, we're just gonna say we want you to generate our HTML file first.
[00:10:14]
So a new htmlWebpackPlugin with this configuration of inject: true. Frankly, I don't remember what that one does. I think that's injecting the paths, but someone double checked me on that. The publicPath will be /assets, cuz I think that that's where all the final things will be. This is basically telling it how to formulate that final HTML doc, and the template will be one that we're about to create, which is ./index.html, okay?
[00:10:50]
>> Brian Holt: And then output, the RSCs are a little specific of how they want to interact with their bundles, so that's what this is all about. We're telling it basically we're gonna make it one chunk as opposed to trying to make it into multiple chunks and how we want them to be constructed, so chunkFilename: development.
[00:11:18]
So if it's in Dev, do (id).chunk.js. This is helpful for just identifying where something is, and if it's going out to prod, we want it to have the hash in there.
>> Brian Holt: Some of this may not be totally necessary to get this all working locally, but I'm reticent to improvise webpack on the fly, as some of you might understand cuz it's a scary thing, webpack is scary.
[00:12:01]
Path is path.resolve_dirname. Because we're on CommonJS, we don't have to define dirname, that's an advantage here. dist, that's where we're gonna put everything. filename is going to be (name).js and clean is true. I believe this is clean up after yourself, is what that does. And then optimization,
>> Brian Holt: Optimization is going to be a runtime chunk.
[00:12:40]
We just want that all to be in one chunk, so runtimeChunk is single.
>> Brian Holt: Okay, and then module.exports = config.
>> Speaker 2: Looks like you might have missed again the React server impact.
>> Brian Holt: The most important one, right?
>> Speaker 3: Right after 32.
>> Brian Holt: That's hilarious, okay, thank you. In plugins here we have new HtmlWebpack, I was just saving the best for last.
[00:13:10]
So [LAUGH] we need one more thing, which is this new ReactServerWebpackPlugin, and we have to say that this is server: false.
>> Brian Holt: So this is, again, we're saying, when you run into one of these React server components, treat them as they're supposed to be treated, as a stub.
[00:13:32]
This also handles things like server actions, all those various features of RSCs. That's all wrapped up into this ReactServerWebpackPlugin. Again, this does work with Vite. You can make it work with Vite, you have to write a little wraparound of this is how you get this webpack plugin to work with Vite, cuz they're all just transformations at the end of the day.
[00:13:59]
>> Brian Holt: Okay, again, not a webpack class, we're not gonna dive too deep here, that's why I wouldn't fault you again if you just copied and pasted this one. We're gonna make our Babel config, not a Babel class, babel.config.js. And we're gonna put the same const development = (process.env.NODE_ENV)
>> Brian Holt: Or this is going to be equal to development and triple equals development.
[00:14:37]
So if you don't have a NODE_ENV, just assume it's node of development, is what that does.
>> Brian Holt: And then module.exports= blah, preset, presets with an S, and nested arrays, obviously @babel/preset-react. I used to have to teach this every single time, and people would just glaze over we went over the babble section.
[00:15:14]
It's nice, cuz Vite just handles all this stuff for you. Okay, so there's that, and then we have to give it an object of configuration which is going to be runtime. Not that runtime, thank you, runtime: "automatic". Used to have to tell Babel what version of React you were using, and I still find it annoying that they don't do this automatically.
[00:15:44]
Automatic just says, look at the package.json. If you wanna know what version of React I'm using, use the package.json, but they don't. useSpread: true and development, I think you can put either just development like this. Or we can say, true, just cuz we're gonna be in dev either time so, either way.
[00:16:09]
>> Brian Holt: Up to you. Okay, so, that's our babel config, let's make our index.html
>> Brian Holt: Again, this is gonna feel real familiar to most of you.
>> Brian Holt: Drop that. This is gonna be, No Framework RSCs. We're gonna put a link in here as well, to index.css. Okay, and then we have to give it as well.
[00:16:50]
Yeah, that should be good cuz it'll inject everything else for us. Okay, so we have to do body, I give it a class here of doodle. This is for our CSS, this will make it all kind of cartoony, or I feel it more like hand-drawn, and then we're gonna do a root here with ROOT, like that.
[00:17:16]
Okay, I should be it. Yep, so, nothing too groundbreaking there, this is the same one that we refer to in our Webpack config, if you remember. Cool, we need to go get a SQLite file, cuz we're gonna be using a little database, which is fun. So go ahead and grab that, you can grab it from a number of places, but.
[00:17:40]
The file that I want you to have here is this notes.db I have it in a different place, but feel free to just copy it out of your clone repo, however you wanna do it. I know I have it laying around on, it's gonna be personal, note-passer. And I have notes.db and I'm just gonna copy it right there, so you can see there I have notes.db that's the one that came from the repo.
[00:18:12]
Yeah, and then you also need the CSS file as well. So, that one you can just copy the whole thing if you want to, which is gonna be, which one do I have here? This is index.css.
>> Brian Holt: So, let's go ahead and grab that one from completed, no framework.
[00:18:38]
Did I put it in source, is that where I put it?
>> Speaker 3: Public.
>> Brian Holt: Public, thank you. Yep, let's just grab this one, I'm not exactly sure which one I use, so we'll just grab this one, make sure we get the right one. And yeah, let's make a public directory here.
[00:18:58]
We're gonna make a new file, index.css, we'll paste that in here. Okay, great.
>> Brian Holt: Okay, now in your package.json, we're gonna add two different scripts here. We're gonna add one for dev:client, this is gonna run Webpack for us, webpack -- watch. And then we're gonna also do one for dev:server, and this is gonna be node -- watch -- conditions.
[00:19:39]
This is a new one for some people, react -server and server/main.js. Conditions, this is a node thing, and I'll be honest you, I didn't even know what this was until I started doing react server components. It's this thing that you can pass into node, that just lets you know where is this running?
[00:20:00]
Run this version of my dependencies, essentially, this lets specifically, that react Webpack plugin that we're gonna incorporate into our node server. It lets it know that this is the server side rendering, not the client side rendering. So make sure you're doing everything from the server perspective. So it's essentially like a massive if statement to the entire app running, and you could have multiple conditions.
[00:20:28]
This is a thing built into node, I just have never used it before, so I don't know where else this is practically applicable, but it does exist, in case you were wondering, which no one was. Yeah, it's letting react know how to resolve its modules. So it's actually hooked in directly to the modules system itself.
[00:20:48]
So, if you require a client component, it's not going to try and load it. That's actually the important part here, otherwise it would crash the server. This gets us started in terms of just getting all the machinery around, getting this working. Now we can actually start writing the server and writing the components for this.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops