Most of the code in an Nx monorepo should live in the
libs section of the workspace. This will not only help you better scale it as it grows but also help you improve your overall architecture. In this lesson, we're creating a library that hosts a routed component for visualizing the detail of a board game from our toy store application.
Instructor: [0:00] This is the toy application we've been using for exploring functionalities of our NX workspace. What we would like to add now to that application here is that whenever you click on one of these cards, you actually see a detail appear at the bottom here.
[0:16] We obviously want to use the routing functionality, the React in this case. Whenever you click, we push in you link to the URL bar and then automatically the DDL should pop-up below here.
[0:27] Normally, what you would do is you would go to your application which in this case is store, creating a new folder here, create your router component that shows the detail and just like then reference it within that App DSX file.
[0:40] Now, in an annex workspace, like in this monorepo setup, you might want to do it a bit differently. As I mentioned earlier, what you would like to have or to try for is to have a less logic in that App folders up here and push everything down to the libs folder.
[0:58] There are multiple reasons for that. First of all, for usability. The more code is in the libs folder, the more you can reuse it. They're maybe not 100 percent ready for being reused, especially cross applications, but they're 90 percent there.
[1:14] You have already that kind of unit, which you can take and import somewhere else and use its functionality. The second part, which is maybe even more important, is Bounded Contexts. What Bounded Contexts are is basically to group together some cohesive functionality.
[1:32] Whenever you're creating a new library in that libs folder, you have to think about a couple of different aspects. One of them is what you want to expose to the outside world and what you want to keep inside. That's your context basically.
[1:45] For instance, here in our UI shared library, we have just one component, which is the header component. That has already been created and meant to be shared for being consumed by some application. In this example, our store app.
[1:58] For that reason, we exported it in our indexjs file. We could actually split that up in a couple of different components here, which live inside our UI shared library folder here but are not meant to be exported. They will be private to that library.
[2:13] Those Bounded Contexts basically make you think about what is private and what is public. Furthermore, as a side effect of NX basically, they also help speed up the whole compilation -- testing, linting, and so on. We will talk about this specifically at a later point.
[2:32] Back to our routed component. For that that purpose, we are going to create a new library down here, which is supposed to contain basically all of the features related to showing a game detail. We will create a new React library again using Nx's capability of generating code.
[2:49] Again, we use now React this library and we give it a name. We could call it future game detail. Since this is specifically for our store app, at least for the moment, we want to also generate it in the directory store and we also give it an app project, which is store.
[3:05] The app project flag here allows us to generate a router component immediately in our store app and link it to our future detail library here. Now when we run this, we see we get here our future game detail library, again, with some React component already pre-generated, which right now doesn't have much in it rather than a message.
[3:26] What you also see in the console output here is we don't only create files, but we also got some code updated. This is one of the big powers also of the generators that come with Nx because they're not only allowing you to scaffold new files, but are also intelligent enough to insert code in existing files.
[3:45] Right now, what it did here in that App.tsx file is to actually insert already some routing for us. If we scroll down here, we can actually see here start of routes and there are a couple of route examples that are being inserted inside here. Let's quickly start our application and have a look at that.
[4:02] If we go over to our app and refresh, we can see here at the bottom, we have basically the routing and you can see how the URL properly updates. We also see that our component gets loaded, which we just generated and there is just another example page that allows you to jump around between different routes.
[4:18] Now, as an example, we are obviously going to modify that slightly because we don't need all of those generated routes. What we need though is our specific route component that features our new generated routing feature detail component.
[4:32] I'm going to cut that out and remove all of our routings, and we just insert our new component. We also might want to slightly change here to pre-generate URL. In our case, we want to basically load a game whenever someone [inaudible] game with a variable ID, of course.
[4:53] The component has already been imported for us. At the very top here, you can see it got imported from that new path mapping that has automatically been generated again. For this to work properly, we also might want to add here an onClick, let's add here onClick.
[5:08] We used the history API for that. That's just like import, use history and here we can say const history=use history. I'm going to push into that history. We reference here X.ID, which is the ID of our game. Also, what we might want to do is actually update our store game detail component here. Let me paste in some more code that makes a lot more sense.
[5:35] In this case here, basically I'm reading the parameter from the URL, and show it in a nice material cart component. Let's save this again. Our complier in the background still runs. Whenever I jump over again to our game here, let's reset the URL, which we changed.
[5:51] Now, whenever I click somewhere, you can see that the parameter gets properly read from the URL, and we load up our detail below.