If you are building a serious app, you most likely have multiple projects you are managing in different repositories and on different team members. Projects such as multiple frontends that communicate with each other backends, shared common businesslogic or even components.
The benefit of splitting your codebase into independent versioned packages is extremely useful for sharing your code.
However, managing changes across multiple repositories can quickly become yucky. Monorepos tries to solve this problem among many others while maintaining organisation wide practices.
In this article we take a look Nx and the nice tooling for creating and managing monorepos.
Our product manager told us to create an application where Users can look at different fruit. He also wants an admin panel where he and other admins can manage what fruit to be in the shop.
We create our workspace by running the command:
We are given some options including the name of our workspace followed by some default setups. You can go ahead and choose whatever you like. In the example we create an empty workspace. The workspace should look a lot like this:
apps ( where our apps go )
libs ( shared libraries: ui, interfaces etc.)
tool ( scripts that act on your codebase: db, custom build etc.)
Give a week of meetings with our product owner and the team. We decide our server should be a Nest.js with a client-app in React and an admin-panel in React.
We can use the CLI to generate these libraries and apps for us:
nx generate @nrwl/react:app fruit-shop
nx generate @nrwl/react:app fruit-panel
nx generate @nrwl/nest:application fruit-server
Okay, so that's cool but we could do this in a regular "single repo, many projects" kinda workspace as well. Where Nx really is different is its tooling.
We notice a lot of code duplication in our client-app and admin-panel to improve our codebase and serve the purpose of DRY. We create a component library:
nx generate @nrwl/react:library ui
But how do we keep track wether or not the library actually affect changes in our app? Nx dep-graph is a tool which detects apps/libraries are affected by the change you just made.
Our newly created fruity-button-component is implemented in both the client-app and the admin-panel. With a few modifications we make a more generic component in the ui-library.
We use the new button in both apps and if we make modifications to the button both apps are affected:
Here we can see the dependency graph for our apps. Pretty sweet. But what's even more better is, Nx can see affected apps within your changes.
Our apps + the server has a dependency to the Users-model in the models-library. Let's change the interface a bit and see which apps are affected by the change:
As we can see all of our projects are affected by this change. There are all sorts of filters that lets you focus on a specific app or exclude apps. Also, it lets you group dependencies by folders.
Many may say that they don't want to develop in a monorepo because they need to build and run test on apps they didn't even affect. With Nx, that's a different story. Nx benefits from knowing which apps are affected by change and therefore knows what kind of test, e2e and builds it needs to run.
For now, we have used the Nx CLI to generate our apps and libraries. But Nx offers a vscode-extension, which can help run commands in a GUI, so you don't have to remember the commands or the documentation.
There's a lot of benefits running a serious application with a tool like Nx. The dep-graph and code/boilerplate generation through the Nx CLI makes it easier to work and collaborate on larger codebases.
I would even consider using this in a smaller app, due to the great tooling behind Nx.