Node Monorepos with Nx

Rate this content
Bookmark
Github

Multiple apis and multiple teams all in the same repository can cause a lot of headaches, but Nx has you covered. Learn to share code, maintain configuration files and coordinate changes in a monorepo that can scale as large as your organisation does. Nx allows you to bring structure to a repository with hundreds of contributors and eliminates the CI slowdowns that typically occur as the codebase grows.


Table of contents:

- Lab 1 - Generate an empty workspace

- Lab 2 - Generate a node api

- Lab 3 - Executors

- Lab 4 - Migrations

- Lab 5 - Generate an auth library

- Lab 6 - Generate a database library

- Lab 7 - Add a node cli

- Lab 8 - Module boundaries

- Lab 9 - Plugins and Generators - Intro

- Lab 10 - Plugins and Generators - Modifying files

- Lab 11 - Setting up CI

- Lab 12 - Distributed caching

FAQ

Node Monorepos with NX is a workshop tailored towards using Node.js as the framework within NX, which is framework and language agnostic. It focuses on managing codebases in a monorepo setup, where multiple applications can coexist in a single repository, improving code sharing and dependency management.

The benefits of using a monorepo include atomic changes across multiple apps, easier code sharing, and a single set of dependencies which simplifies management and reduces conflicts between different versions of the same dependency.

Yes, NX is framework and language agnostic. It can be used with front-end frameworks like React or Angular, and it supports various programming languages including Java, Python, and .NET.

A monorepo involves managing multiple projects within a single repository with tooling support to handle complexities like dependency management and testing scopes. Code colocation, on the other hand, is simply placing multiple projects in one repository without any specialized tooling, which can lead to maintenance and scalability issues.

NX improves efficiency by using techniques like affected command detection to run tests and builds only on affected projects, caching results for faster subsequent builds, and providing tools for controlled code sharing and consistent coding practices across teams.

In a monorepo setup, NX can detect changes in a shared library and automatically run tests for dependent applications. This immediate feedback loop helps developers fix issues quicker, ensuring that changes in one part do not adversely affect other parts of the application.

NX supports distributed caching through NX Cloud, which allows build artifacts to be shared across a team or organization. This means that if one developer builds a project, the results can be reused by others, significantly reducing the build time across the team.

Isaac Mann
Isaac Mann
160 min
06 Apr, 2023

Comments

Sign in or register to post your comment.

Video Summary and Transcription

This workshop explores Node Monorepos with NX, highlighting the benefits of monorepos and NX in managing complexity, code sharing, and dependency management. It covers creating and using libraries, setting up module boundaries, linting, and CI/CD integration. The workshop also introduces NX Cloud, which offers distributed caching and task execution for improved performance. Overall, the workshop provides practical insights and tools for efficient software development and engineering in a monorepo environment.

Available in Español: Monorepos de Node con Nx

1. Introduction to Node Monorepos with NX

Short description:

Welcome to Node Monorepos with NX. This workshop will be tailored towards Node as the framework used with NX. NX is framework and language agnostic, allowing you to use front-end applications like React or Angular, as well as other languages like Java and Python. Monorepos offer benefits such as atomic changes, easy code sharing, and simplified dependency management.

All right, okay, so welcome to Node Monorepos with NX. This is great. So I am, my name is Isaac Mann. I'm an architect at NX. We've been, I've been working with NX for four years. I've been an employee of NX for four years. I used it for two years before that. And yeah, this is exciting.

So this workshop will be tailored towards Node as just the framework that we'll be using with NX. But NX is, you know, is pretty much framework and language agnostic. But we'll get into that more. So it's, you know, you can use front-end applications like React or Angular or you know, whatever other front-end technology you're using. You can also use other languages like obviously people use Java and Python and.NET with NX. So NX is all about, you know, managing your code base and whatever code you're using is this is node monorepos with NX.

And first, we're going to start with a little discussion of, why you would want a monorepo. So a monorepo is any repository that has more than one application living in that, in that codebase. So what's the benefit of a monorepo? So three kind of big categories of benefits for monorepos. Monorepo give you atomic changes, allow you to easily share your code and give you a single set of dependencies, make it easier to manage those dependencies. So we're going to dig into each of these three things and explain what they are and why they're beneficial.

2. Benefits of Monorepo and NX

Short description:

A monorepo offers benefits such as atomic changes, easy code sharing, and simplified dependency management. It allows for faster command execution, targeted testing for affected projects, and local and distributed caching. NX provides tooling to help achieve the benefits of a monorepo without the drawbacks of code colocation. It enables controlled code sharing and efficient management of dependencies.

So if you had an application and a kind of a library that is, that is used by that application. And if you have them managed in two separate repos, let's say you make a change to the UI library that's in repo two at the bottom here. If you make a change to it, and for some reason it breaks the homepage application, you, the, the lifecycle of that change would be so somebody makes a change to the common UI library. They push up the commit, they incommit the version at some point later somebody tries to use that new version of the common UI library in the homepage app. They realize there's a, there's a breaking change there and it broke their application. So they file a bug with the common UI library, and they say, Hey, you gotta fix this. And then later once the UI library developer sees that she sees that problem they, you know, they make the change, they push a new fix up new version, and then the homepage app, people later have to you know bump the version to the fixed fixed version, and then see if it see if it fix their application. So that that whole cycle, typically, I mean the best case scenario few days, it can take a week or two if if people are not you know working on these things full time.

So, one of the issues here is, if you were to put both those library, the library and the application together in the same repo, then that that cycle would be, it would be just the UI library creator, making a change, running the tests and seeing Oh, it broke the tests in the homepage app, I've got to fix that. And that so that that cycle took will take like a half hour an hour. Like, even before you've pushed up a PR, you'd notice that you broke the application, you have to make, you know, modify your code. So, that's so you have in one PR, you know, whether you know, all the changes that you need to make to the application or changes that you know, you need to make the UI library to adapt to the application itself. That's that's one benefit of a mono repo. Second benefit is shared code. Let's say you have some logic about you know, what is a valid username? And you know, this function, it's obviously, the different scenarios, you'd have a, you know, more complex function than this, you're handling whether username was valid. But let's say you want to share this across your application across multiple application, multiple libraries. If this ever were to change, you'd have to update that in every single repo that's using it. If you're if you're copying the code from repo to repo, whereas if you're in a monorepo setting, you can just use this function. And whatever that function changes, then your, your behavior changes across the whole, the whole repository, wherever it's being used. So easily sharing code. Third thing is having a single set of dependencies. So if you have a framework like Node, or in this case, and the picture is react, if you have different versions of that framework being used in different applications, you can run into very strange, hard to debug runtime errors. And, and having your code in the same repository will basically forces you to have, well it can you can set rules in place to force yourself to be on the same version for everything that's in that repo. It is possible to have multiple versions of the same mono repo, but it's, it's better to have a single version and make things easier in the long run. So basically in in a large when you have multiple applications, typically you have one application that you're working on all the time, that it's on the latest version of whatever dependencies you you have, but if you, you're going to have, you know, two or three other applications that they get worked on maybe once every couple of months and those inevitably fall behind and you, you have to remember, okay, how did I upgrade that framework? Um, you know, this, the six months ago upgrade, and you have to remember and go through all that same work again. Um, whereas if it was, if you were upgrading all your applications, all three applications at the same time, it's a lot easier than upgrading three different applications, different points over the course of a year and a half. Um, so you just do it all at once and it's a lot easier than, than doing it spread out over a year or whatever, whenever you think of updating those applications.

So, one way of, you know, having a, um, a mono repo, um, so the difference between a mono repo and code colocation and code colocation is when you just dump all the applications together in the same repo without having any tooling to manage that. And that, that can be a nightmare. If you just dump it all together, um, you can end up with a scenario where you're running unnecessary tests. We have no code boundaries and all the code just gets mixed up together and it's hard to maintain. Um, and you can have inconsistent tooling where you have conflicts between how those tools interact with each other like your testing tools or your, uh, whatever other tools you have.

So, NX is a tooling to help you, uh, get all the benefits of a monorepo without the negatives of code colocation. All right. So NX gives you a faster command execution. So, um, executors are basically, um, like, uh, NPM scripts, um, that can help you, um, you run your, um, your build and test and lent and all the actions that you take on your code. Uh, NX affected is the tool that, that lets you run the tests for only the projects that are affected by a, uh, by a code change and not the tests that are unrelated. Um, and then we have local and distributed caching. So anytime you run a command, um, and, uh, if you run that same command again without changing the code, it just uses the, instead of actually running the build again, it just uses the, the cast version of that, um, of that output and, um, without, you know, actually, um, running the build again. So if, if your bill takes, you know, a minute and a half, um, if you run that build again, instead of taking a minute, a half, it'll take a second or two just to pool that, that data from the cache and to replay the terminal output for you. Um, so that's just locally. That's, that's completely free. That's in the open source NX. Um, then with a NX cloud, you can use the distributed caching. So that, that same caching behavior that you get, um, on your own machine, you can share that cache across your whole organization. So if anybody anywhere has run this command with this same code, you can use their cache and replay it yourself. So this, you know, particularly for PRS, you, you run your code, you push it up. Um, the runs in CI and then somebody else checks that branch out on their machine and they run the same thing. They can, um, just use your cache version instead of running that same, um, you know, computation on their machine again. Um, so basically you, you only run, um, the actions for a particular set of code one time across your whole organization, which is, um, and that's also, it's not just for, um, uh, that that's broken up by projects. So if you have, um, one application that depends on five different, um, libraries, um, that's the, the library build step is cached as well as the application build steps. So say you change just the application, those five libraries, their build output is already cached for you. And then, so you can just use that cache and then only do the last application built step, which can be game changing for large code bases. Um, and X also gives you controlled code sharing. So you, you set a, an index.ts file at the root of your, um, each project.

Watch more workshops on topic

React at Scale with Nx
React Summit 2023React Summit 2023
145 min
React at Scale with Nx
Top Content
Featured WorkshopFree
Isaac Mann
Isaac Mann
We're going to be using Nx and some its plugins to accelerate the development of this app.
Some of the things you'll learn:- Generating a pristine Nx workspace- Generating frontend React apps and backend APIs inside your workspace, with pre-configured proxies- Creating shared libs for re-using code- Generating new routed components with all the routes pre-configured by Nx and ready to go- How to organize code in a monorepo- Easily move libs around your folder structure- Creating Storybook stories and e2e Cypress tests for your components
Table of contents: - Lab 1 - Generate an empty workspace- Lab 2 - Generate a React app- Lab 3 - Executors- Lab 3.1 - Migrations- Lab 4 - Generate a component lib- Lab 5 - Generate a utility lib- Lab 6 - Generate a route lib- Lab 7 - Add an Express API- Lab 8 - Displaying a full game in the routed game-detail component- Lab 9 - Generate a type lib that the API and frontend can share- Lab 10 - Generate Storybook stories for the shared ui component- Lab 11 - E2E test the shared component

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Levelling up Monorepos with npm Workspaces
DevOps.js Conf 2022DevOps.js Conf 2022
33 min
Levelling up Monorepos with npm Workspaces
Top Content
Learn more about how to leverage the default features of npm workspaces to help you manage your monorepo project while also checking out some of the new npm cli features.
End the Pain: Rethinking CI for Large Monorepos
DevOps.js Conf 2024DevOps.js Conf 2024
25 min
End the Pain: Rethinking CI for Large Monorepos
Scaling large codebases, especially monorepos, can be a nightmare on Continuous Integration (CI) systems. The current landscape of CI tools leans towards being machine-oriented, low-level, and demanding in terms of maintenance. What's worse, they're often disassociated from the developer's actual needs and workflow.Why is CI a stumbling block? Because current CI systems are jacks-of-all-trades, with no specific understanding of your codebase. They can't take advantage of the context they operate in to offer optimizations.In this talk, we'll explore the future of CI, designed specifically for large codebases and monorepos. Imagine a CI system that understands the structure of your workspace, dynamically parallelizes tasks across machines using historical data, and does all of this with a minimal, high-level configuration. Let's rethink CI, making it smarter, more efficient, and aligned with developer needs.
Federated Microfrontends at Scale
React Summit 2023React Summit 2023
31 min
Federated Microfrontends at Scale
Top Content
The talk will be a story of how Personio went from rendering through a Monolithical PHP architecture, to a microfrontend oriented Next JS app, powered by Module Federation and the NX monorepo toolchain.
Scale Your React App without Micro-frontends
React Summit 2022React Summit 2022
21 min
Scale Your React App without Micro-frontends
As your team grows and becomes multiple teams, the size of your codebase follows. You get to 100k lines of code and your build time dangerously approaches the 10min mark 😱 But that’s not all, your static CI checks (linting, type coverage, dead code) and tests are also taking longer and longer...How do you keep your teams moving fast and shipping features to users regularly if your PRs take forever to be tested and deployed?After exploring a few options we decided to go down the Nx route. Let’s look at how to migrate a large codebase to Nx and take advantage of its incremental builds!
The Age of Monorepos
JSNation 2022JSNation 2022
25 min
The Age of Monorepos
The history of the web can be divided into evolutionary development leaps. The age of inline scripts, the age of jQuery, the age of SPAs, the age of JAMStack...We are now entering the next stage that has been carefully prepared in the past few years. Let me invite you to the world of modern monorepo solutions and share with you the benefits you will reap by using them in every project size and setup. It's time you automate those boilerplate tasks and reduce the bottlenecks so you can focus on what truly matters.Get ready for the next leap! Welcome to the age of monorepos!
Remixing Your Stack in a Monorepo Workspace
Remix Conf Europe 2022Remix Conf Europe 2022
22 min
Remixing Your Stack in a Monorepo Workspace
Remix entered the stage with a unique and refreshing take on how to develop on the web. But how do you integrate it into your existing ecosystem of applications? Do you want to test-drive Remix on a small project, or do you want to go full-in, but it is tricky to do a big-bang migration from your existing React app? In this talk, we're going to explore how a monorepo-based code organization can help integrate Remix with your existing React and TypeScript infrastructure, facilitating high code reuse and a migration path to Remix.