Can we combine a NestJS app with React?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey how's it going today we're going to talk about how you can combine a net stress application with a react.js application into a single mono repo imagine that you're trying to create a full stack application JavaScript or typescript both on the front end and the back end you know you want to use react.js on the front end now most people that have this use case probably should just consider next.js which is a pretty good meta framework for react and it also serves as basically somewhat of a backend framework that allows you to do you know your own API routes you can do server-side rendering static site Generation Now however you might be thinking where does nest.js come in if we're already using next.js for the full stack well let's quickly take a look at what next.js offers out of the box in terms of you know a back-end framework so they have this concept called API routes which is almost very similar to what you might see from something like Express which means that you know by Design it's pretty minimal and it kind of asks you to figure out the rest of the architecture for yourself for example perhaps you're trying to do graphql they have a link here for how to do that with graphql yoga but it doesn't tell you really how it just shows you an example whereas if you compare this with the nexjs documentation you can see that they have graphql as a first class thing that they support now graphql is just one thing right but there's also things like how do you do authentication authorization how do you connect to databases how do you do Swagger docs if you're using rest or perhaps web sockets and a bunch of other things like event driven architectures there's a lot of things in sjs that you can do out of the box it has first class support for a lot of these things that next.js will you know basically tell you hey figure it out on your own so that's where I can see the use case of people selecting nest.js as their primary back-end framework because of all these things that it basically out of the box supports now if you did decide to use nest for your backend framework that means that you kind of have to split up your application into effectively two applications right where you have nest.js in the back and next JS and the front end which this totally could be a valley combination however since both of these are technically server Frameworks right that means that you likely are are going to have to spin up two different servers to make your application run which could be fine for you but for others maybe not so much one thing to think about though is if perhaps you don't need server-side rendering or static site generation you probably could just get away with doing a single page application right like basically react on its own and then just have your nexjs application serve that up in production and this is exactly the use case that I do want to cover in this video you know how do we create a monorepo that has both of these things together you can build your entire project as you know one running server that effectively has both of these things so I've got a terminal here open you can see that I'm using node 18 and npm8 you do need to use one of the newer versions of npm that supports workspaces which we need for our mono repo alright so to get started create yourself a directory for your application I just called my Nest react go into that and immediately we're going to install a dependency let's do npm install Dash the turbo and then I'll actually just open this up in vs code and we'll continue from there all right so here's our application not much in here yet you can see the turbo under our Dev dependencies here we are going to add something here in package.json which is workspaces which takes in an array and you can pass in here a path of a pattern where all your workspaces will be in our case we're going to put our applications in an apps folder so on the left side here I'm going to go ahead and create that new apps folder now I'm back in the terminal here's to start you know creating those new applications if you're not familiar with Nest it does come with a CLI that you need to install globally so if you haven't done that before do npm install Dash G at netjs CLI at latest once you have that installed we're going to go to the apps folder and then we'll use that CLI to install a new project we're going to do Nest new API and then we're going to say we're going to use npm because that's what we started with you can see that this already installed pause the packages for you right so you can see on the left here our application is created we'll get back to this code in a second but let's also create our client application while we're in the terminal now for the react application I'm going to use Veet you can just do npm create V at latest and then the name of your project this one I'm just going to call client to keep it simple and make sure to select react here and typescript now one thing to pay attention to here is that it doesn't do the npm install for you so we're gonna do that so I'm just gonna do npm install at the root of our project you might be wondering why didn't I do that in the client folder well the way that workspaces works is that basically it'll look at all the individual package that jsons that you have right both in API and also in a client folder there's a package that Json in there so even if you install at the root and really you should be installing at the root it'll it should resolve your dependencies correctly alright so at this point we got two applications we've got a nest API and a react client now we need to start thinking about how do we work with both of these applications at the same time right so for example when you're developing locally it would be great if both of them are running at the same time or perhaps at deploy time you want to be able to build both of these at the same time right so that's where Turbo repo comes in it's a tool that helps you basically get a monoree pool up and running very quickly to get started we're going to create a new file at the root we're going to call it turbo.json and I'm going to pay some initial config here that you can feel free to pause screen and copy now you don't have to fully understand how turbo repo works just to get started with it it can be pretty simple and but you can hover over some of these to get a glimpse of what this is supposed to Define so for example pipeline is an object that represents the task dependency graph of your project within that you can put in tasks that if turbo finds a workspace package with an npm script that matches this key it's basically going to run that across your different applications so so what does that mean now in our client notice that if we go to the package.json in our client you can run our application using npm run Dev let's take a look at API it also has a package.json that has its own scripts it also has a Dev script but it's called start Dev we're actually going to simplify this to just be Dev so that it's matching now while we're here I'm actually going to add a flag here preserve watch output which basically says that as we change the code don't clear out the terminal right so at this point we have an npm script Dev for both API and client and in Turbo repo we said that we have this task here called Dev so it's going to look for those npm scripts so for us to run this task we're also going to add a script in the root package.json and I'll also just call this Dev to be consistent and we're going to do turbo run Dev let's go ahead and go to our terminal and run and pin run Dev and see what happens so you can see that effectively we ran turbo run Dev which says that it goes into this configuration that we had and it says we have a task called Dev and what that's going to do is go into the individual applications that we have look at their package.json and run the dev commands for each one of them because it matches the same key that we have here right so you can see that now both of our applications are running we can check this real quick so our react application is running under localhost 5173 so on the browser it should look like this and then our next application is actually by default running on localhost for 3000 so if we make that request there you should just see a hello world right so that just proves that you know they're running together and also that's again why we added their preserved watch output earlier so that you can see all of these logs and it's not being cleared out by Nest now it's important to quickly explain how our local development setup differs from our production setup when we actually did deploy our application together so what we effectively have is two different servers running side by side right so you can imagine that we're really running webpack which serves nest.js and then for the client side we have Veet which is you know serving up our react application and both of these guys are waiting for code changes and will automatically refresh the application however in our production environment that's not how it works right we will have a single server so imagine that we'll have a build for our Nas application and we'll have a build for our react application and you can imagine that the build of our Nest application is just something that you can run via node right it doesn't need a webpack server it just runs on node and one of the abilities that we're going to add to it is that it's going to be able to serve up the client build to a browser and similarly we have an API that effectively is coming with our Nest application so our client itself can also make requests that right so I hope that makes sense I'm over simplifying it a little bit but that effectively is going to be the end result that we're going to have at the end of this video Now quickly we need to talk about in local development if we have two separate servers how do you proxy requests from the client to the server side for example if there's a running server here and the client makes a request to slash API how does it know to forward that to our Nest application if they're running into different servers now luckily this is actually something that V directly supports so let's go ahead and configure that and let's take a look at our vconfig this is the one under apps client and we're just going to add some server configuration in here that says proxy if you see this path of Slash API make sure to proxy that to localhost 3000 which is our local Nest app now that does mean that every request that we're trying to make to our Nest app has to have this base slash API so I'm also going to configure our nest API to have that base path of Slash API for all of its routes so to do that in main.ts I just need to add app that set Global prefix API now if you're getting a little lost on what I'm trying to do here go ahead and run your application and let's do a quick demo previously on localhost 3000 you know we got back the hello world because you know that's just where it ran by default that the default slash so if I refresh this it's actually not going to be a 404 because we said that the global prefix is now slash API so you have to go to slash API on localhost 3000 to get back that response now what we're going to do on the react application is we're going to do a request to that slash API so that we get back that hello world greeting alright so this time let's move over to the the client-side react application let's go to the app.tsx which is showing that thing you see in the browser earlier with the react and Veet logo I'm just going to clean this up and remove these things and then we're going to display our greeting in here so imagine that we have a greeting State let's go ahead add and update this use State up here to greeting set greeting and then we're just going to add a simple use effect here that is going to make a call to slash API which we said is going to proxy to our Nest API and then we're just going to get the text from that and then set the greeting from that response right so we expect that to be hello world and then make sure to import use effect by the way if you haven't already I made a small typo actually here there shouldn't be an extra curly brace here thinking of handlebars there for some reason so what effectively is going to happen when this when this application mounts right it's going to make a call to slash API it's going to get a greeting it's going to save the reading and it's going to display it over here so let's take a look so now at this point if you're following along your react application should be saying hello world right and remember that's coming straight from our Nest API so we know that the proxy is happening now in production it doesn't need to do any proxying right because it's just making the the request directly to the same server so you don't have to worry about it so this is really just a proxy for local development all right so at this point imagine you know you're done with your development maybe you're ready to deploy a new feature you need to think about how do we build both of our applications together and similarly to how we ran both of our applications together for Dev you can also build both of your applications at the same time so in our turbo.json we're going to add a build key here in our Pipeline and similarly kind of like how we have an npm script Dev for both of our applications we already should have a build npm script for our API if you look in API package.json there should already be a build script here and if you look in our client package.json there should also be a build here that's using TSC and Veet build now we do have to add a couple extra pieces of configuration here we're going to add the pens on and outputs outputs is pretty simple basically when both of our application builds there's going to be a disk directory in both of those applications so this is actually a relative path to each of our applications so when you build the nest and when you build the react they both have a dist folder in there so we're just letting turbo repo know where that is and then depends on is basically just a you know it's starting to build a dependency graph when you npm run build what does this depend on you know you can list other things in here for example perhaps you have your build depending on tests or linting right if you have npm scripts set up for those it's basically going to run those things before it runs the build in our case here when we have this you know carrot and build if you hover over this it'll say that the symbol tells turbo that this pipeline task depends on the packages you know Upstream dependencies so basically it's saying that it needs to build the dependencies and Dev dependencies and make sure those builds for those things are built before building the application itself I know that's super kind of complicated there are some extra documentation on this in the turbo site itself if you want to read about it but for now feel free to just follow along this is really the only configuration you need all right so for us to test this configuration this task if you remember in the root package.json we added a Dev script there to basically invoke that task we're going to do the same thing we're going to add a build and do turbo run build and we can run this on the terminal to test this out and again remember that what this is going to do is basically call npm run build in all of our applications so in our client and our API so you can see that it actually will try to build both of them in parallel and then we didn't talk about this yet but you can see that there's some caching happening here take a look at what happens when I run build again it'll say that it's already cached it doesn't have to rebuild it just did it in 50 milliseconds it'll know that if the code didn't change it'll just reuse you know the build that it made for you before and that's also why for Dev our Dev script we said cash false because it doesn't really provide us any benefits because we know that the the build for the dev is going to change often right because we're changing the code so caching doesn't really make sense there but for build it does and if you just want to prove that both of our applications built right if you go on apps you should expect to see a disk folder within API right here and there should also be a this folder within client and that's why we said that the outputs is in this and that's some part of the way that the caching works is it looks at the outputs and nodes to reuse what we built before all right so at this point we know how to create our builds you know you can do it in parallel with a single command there's one missing piece that we have which is remember you know we have these separate builds for the react and the sjs application but we said that in production The Nest application is going to serve up our client build to the browser that way we still only have one single server running in production now if you don't know how to do that luckily nest.js has support for serving up a static single page application using the server static module that we just need to install that as a new package to our application and then after that just a little bit of configuration and we'll be done so back in your application to install a new package so remember that you know we have the apps folder and each of these apps have their own package.json you might think that you have to go to each of these folders and run the npm install in there which you don't with workspaces you can just do npm install dash dash workspace and then Define the name of the workspace in our case we're trying to install inside API the nest.js server static package so I'll hit enter here and install that so we're going to go to our app module in API and we're going to add to the Imports here so we added surf static module for root and then we're going to pass in the path to our client build right and also make sure to import that new sub static module but this path if you can think about it is basically you know going back twice so that it goes back to apps and then into client and then into this where it's going to find this index.html which is gonna which it's gonna serve up all right so at this point all we need to do is build our application again and then start our API basically in production mode and if you look at the package.json for API you can see that they have a a start prod script here that basically just does you know node run the application on in this main we're just going to emulate that on the root so on the root package.json I'm just going to add a start script here that does node apps API this main right so that's basically the same thing except it's coming from the root and then at this point I think we're basically done with the code we can go ahead and do npm run build to make sure you know it pulls in those changes that we just did with serve static and then we should be able to do npm start which is going to spin up our Nest API server in production mode and then serve up our client build right so you can see our application successfully started and going back to localhost 3000 which is technically our Nest application right you can see that it's now serving up our react static build right so going back to our drawing here what's happening is we have a single running net server that is serving up this react client build to the browser right and we can see that it's still displaying the hello world because it's making that call to just the server itself bring us back that hello world response and there you go you've got an end-to-end full stack setup for react and nest.js alright guys hopefully that quick mono repo tutorial was very useful to you let me know in the comments what you think would you do it this way would you do it another way I'd love to know what kind of feedback you have also do make sure to subscribe if you like content like this I have a lot more planned uh this year so make sure to subscribe and hit that Bell to get notified and I'll see you in the next video
Info
Channel: Marius Espejo
Views: 10,677
Rating: undefined out of 5
Keywords: monorepo, turbo, turborepo, turbopack, nestjs, reactjs, react, nest, typescript, nest react, serve static, expressjs, javascript
Id: nY0R7pslbCI
Channel Id: undefined
Length: 20min 43sec (1243 seconds)
Published: Mon Feb 13 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.