React at Scale with Nx

Rate this content
Bookmark

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

FAQ

A MonoRepo, or monolithic repository, is a single repository that contains multiple distinct projects with well-defined relationships. This setup allows for easier code sharing, atomic changes across projects, and streamlined dependency management.

The benefits of using a MonoRepo include atomic changes, simplified code sharing, and a single set of dependencies. This facilitates faster development cycles, reduces integration issues, and simplifies project management across multiple teams or projects.

Atomic changes refer to the ability to make changes across multiple projects within a MonoRepo in a single commit. This ensures that all interdependent components are updated together, minimizing the risk of compatibility issues.

In a MonoRepo, code sharing is facilitated by direct access to the shared codebase within the repository. Teams can easily export and import functions or components across different projects without the need for separate package management.

Without proper tooling, a MonoRepo can lead to issues such as running unnecessary tests, lack of clear code boundaries, and inconsistent coding practices. These challenges can decrease efficiency and increase the risk of errors during development.

Isaac Mann
Isaac Mann
145 min
17 May, 2023

Comments

Sign in or register to post your comment.

Video Summary and Transcription

We discuss developing at scale with NxMonoRepos, which provide the benefits of a monorepo without the drawbacks of code collocation. Nx helps with code consistency and automation through plugins and generators. The workshop covers folder structure, workspace creation, using plugins, updating files, using executors, libraries and migrations, running generators and migration scripts, connecting APIs, creating type libraries, and using generators for Storybook configuration. It also covers configuring Storybook, enforcing module boundaries, setting up CI, using workspaces, and the trade-offs of libraries and applications.

Available in Español: React a Escala con Nx

1. Developing at Scale with NxMonoRepos

Short description:

We're gonna talk about developing at scale with NxMonoRepos. A MonoRepo is a single repository that contains multiple distinct projects with well-defined relationships. A monorepo is great for atomic changes, sharing code easily, and having a single set of dependencies. Code collocation is where you just drop code together without having a monorepo tooling in place. One of the issues is running unnecessary tests, not having code boundaries, and having inconsistent tooling. Nx can help with these problems.

We're gonna talk about developing at scale with NxMonoRepos. So what is a MonoRepo? MonoRepo is a single repository that contains multiple distinct projects with well-defined relationships. So, you know, multiple different apps working together, or you could it could be one app but with multiple like sub projects inside of it. And then you need to have well-defined relationships between them. You can't just if you just dump all the code of two different apps in the same repo. We call this code co-location and it's a mess. And you you'll run into lots of problems with that. And let's talk about what those things are.

So a monorepo is great for lets you have atomic changes, lets you share code easily, and lets you have a single set of dependencies. So let me go into each of these and explain what they are. So atomic changes are, let's say you have an application that consumes a UI library. And if you have that UI library in a separate repo from your application, then the change workflow goes something like this. Say you make a change to the UI library that breaks a test in the application. So you have to publish that UI library, and then at some point later, the application developer bumps up their version of the library and realizes, hey, you broke my application. So then they tell you about it, or they file an issue about it. And then the library developer has to come back and say, okay, I'm gonna fix that bug and then publish a new version of it that will fix the bug. And then later, a few days later, the application developer bumps their version again and says, okay, that fixed it. So that whole life cycle, that's a minimum of a week probably, of actual real developer time. Before the change is made to it's actually fixed and corrected. Whereas if they were the same repo, then the library developer would just run the tests before they even make the commit. They would just run the test and say, wait, I broke that app, I'm gonna fix it. So it goes from a week cycle time to like 30 minutes cycle time and you're not doing that contact switching, going back to this thing you worked on a week ago to finally fix it. That's one benefit of a Monorepo. Second benefit is sharing code. So if you have some user logic to validate whether a username is valid, and you want to reuse that logic across multiple applications or multiple subsections of your app. If you were gonna do that in separate repos, you'd have to publish that and keep the version numbers in sync. Whereas in a monorepo, all you need to do to share that logic is to export a function and then just reuse that function wherever it's needed. So it makes it dead simple to keep that logic in sync. If you wanted to change this logic somehow, you just update that function and everywhere instantly uses the new updated logic. The other benefit is having a single set of dependencies. So, say if you have multiple different versions of your framework of Angular or react, that can cause weird, strange bugs. If you have a library that's on an old version of react and the applications on a newer version of react, there can be like, hard to debug. Hard to debug runtime errors that can be caused by that. The other issue is that whenever you have multiple applications on different, well, you have multiple applications, usually there's one application, that's the main thing that gets worked on all the time. So that's going to be at the latest version of React. Version of the framework, but then if you're going to have another application that's you know you updated every three months or so maybe whenever you get around to it, and then whenever you go to update that, it's always a pain. Because you have to remember, okay, what were the tricky things about upgrading to that version of React that was six months ago, or a year ago. And you have to go through all the same pain points that you did the first time, but 12 months later. Whereas it's a lot easier to do all the application upgrading at the same time. Because you're solving the same problem in 10 different places, instead of solving the same problem in one place, so it's not that hard. Whereas if you do it 10 different times over the course of a year, that's really painful.

Code collocation is where you just drop code together without having a monorepo tooling in place. So one of the issues so you can have running unnecessary tests, not having code boundaries and having inconsistent tooling. So unnecessary tests, let's say you change the products homepage project, and that depends on a UI library. So if you make changes to the products homepage, there's no way you broke the test for the product UI library. So there's no point running those tests, but without your tooling knowing about how this dependency graph, how that dependency actually works. There's no way for your tooling to say, these tests you need to run, these tests you don't need to run. So you need to have something that knows this dependency graph. And so you could theoretically do that yourself. You say I know that this test needs to run, these other tests don't. But a normal repo that has multiple applications, the product graph looks more like this. Or even, I've seen graphs that have thousands of nodes in it like this. And so there's no way you can do that in your head to make sure you get all the tests done correctly every time. So you want to have a tool that can do this for you. So you make sure you run all the tests you need to run, but not any of the tests that are guaranteed not to have broken. The other thing is code boundaries. Let's say you have your code in a shared repo, and you have some function that you're playing around with. It's intended for internal use within your project, and you don't want other people to use it, because it might change frequently, right? But somebody reaches in and starts using that function in their application. And then at some point later, you change it. You've broken their app, and they're upset at you. And so, now you're forever on the hook for keeping that function with the same API, or fixing their code wherever it's using it. So there needs to be some way of saying, these functions are available for you to use. These functions are not available for you to use. So that you can clearly say, here's the boundary, and this is my stuff, internal stuff. This is public stuff. And the other thing is inconsistent tooling. So every application, every project has, you put in NPM script, you have all sorts of weird flags and scripts. And so, whenever you're going into new code base, you have to figure out, what does this mean? And why would I ever run this? And it's really hard to know that in each new application. So you need to have some way of making those things discoverable and well-documented. So this is what Nx can help with.

2. Benefits of NxMonoRepos

Short description:

It gives you all the benefits of the monorepo without the drawbacks of code collocation. Nx provides linting rules, generators, and plugins for consistent coding practices. It allows controlled code sharing and an accurate architecture diagram. Nx understands the dependencies between projects, ensuring accurate task execution and test running.

It gives you all the benefits of the monorepo without the drawbacks of code collocation. So it can give you faster command execution, gives you controlled code sharing, consistent coding practices, and an accurate architecture diagram. So faster command execution. There are executors, which help you run whatever tasks you need to run against your code, the build, test, and let, those kinds of things. Nx Affected allows you to run commands only on projects that were affected by a code change and not anything that wasn't affected. And Local and Distributed Caching also speed up your average runtime in CI or locally by saying if the inputs for this task haven't changed, then I know the output is already what was done before. And so it just pulls it from the cache instead of rerunning. And Distributed Caching allows you to share that cache across your whole organization instead of just locally on your machine. Controlled Code Sharing, you can set up an API for your projects and say these are the functions that are public for anyone else to use and these are anything that's not exported in the API file, that indexed TS file is private so you can't use it. You can set up tags to say these particular types of projects can depend on these other types of projects, but other ones cannot. And so whatever structure you need to make for your own organization, you can say these types of projects can be used within this team and these other projects are shared for anyone to use. So whatever kind of structure you need to make with those tags, you can do. You can also do publishable libraries to publish to NPM. You use a code owners file, which is like a Git feature which says if you make changes within these folders, these particular people have to approve the PR before it can merge. So all those things are useful for managing a large repo. Consistent coding practices, so Nx provides linting rules, generators let you generate code and modify code. So keep things up to date and add new code in a consistent way. There are narrow provided plugins from Nx which are official, and then there are also community plugins. So anybody can write a plug in and publish it and say, this will give you support for some tool that Nx hasn't supported officially. And then you can have an accurate architecture diagram. So Nx understands how the different projects relate to each other. Not just the way you think they depend on each other or the way you wish they depended on each other or the way they depended on each other six months ago. It's what the code is saying about how these projects depend on each other, which is invaluable for really having an accurate view of which tests actually need to be run and how projects need to, which tasks need to be run before which other tasks those kinds of things.

Watch more workshops on topic

React Performance Debugging Masterclass
React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Top Content
Featured WorkshopFree
Ivan Akulov
Ivan Akulov
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
Concurrent Rendering Adventures in React 18
React Advanced Conference 2021React Advanced Conference 2021
132 min
Concurrent Rendering Adventures in React 18
Top Content
Featured WorkshopFree
Maurice de Beijer
Maurice de Beijer
With the release of React 18 we finally get the long awaited concurrent rendering. But how is that going to affect your application? What are the benefits of concurrent rendering in React? What do you need to do to switch to concurrent rendering when you upgrade to React 18? And what if you don’t want or can’t use concurrent rendering yet?

There are some behavior changes you need to be aware of! In this workshop we will cover all of those subjects and more.

Join me with your laptop in this interactive workshop. You will see how easy it is to switch to concurrent rendering in your React application. You will learn all about concurrent rendering, SuspenseList, the startTransition API and more.
React Hooks Tips Only the Pros Know
React Summit Remote Edition 2021React Summit Remote Edition 2021
177 min
React Hooks Tips Only the Pros Know
Top Content
Featured Workshop
Maurice de Beijer
Maurice de Beijer
The addition of the hooks API to React was quite a major change. Before hooks most components had to be class based. Now, with hooks, these are often much simpler functional components. Hooks can be really simple to use. Almost deceptively simple. Because there are still plenty of ways you can mess up with hooks. And it often turns out there are many ways where you can improve your components a better understanding of how each React hook can be used.You will learn all about the pros and cons of the various hooks. You will learn when to use useState() versus useReducer(). We will look at using useContext() efficiently. You will see when to use useLayoutEffect() and when useEffect() is better.
React, TypeScript, and TDD
React Advanced Conference 2021React Advanced Conference 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
Paul Everitt
Paul Everitt
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
Web3 Workshop - Building Your First Dapp
React Advanced Conference 2021React Advanced Conference 2021
145 min
Web3 Workshop - Building Your First Dapp
Top Content
Featured WorkshopFree
Nader Dabit
Nader Dabit
In this workshop, you'll learn how to build your first full stack dapp on the Ethereum blockchain, reading and writing data to the network, and connecting a front end application to the contract you've deployed. By the end of the workshop, you'll understand how to set up a full stack development environment, run a local node, and interact with any smart contract using React, HardHat, and Ethers.js.
Designing Effective Tests With React Testing Library
React Summit 2023React Summit 2023
151 min
Designing Effective Tests With React Testing Library
Top Content
Featured Workshop
Josh Justice
Josh Justice
React Testing Library is a great framework for React component tests because there are a lot of questions it answers for you, so you don’t need to worry about those questions. But that doesn’t mean testing is easy. There are still a lot of questions you have to figure out for yourself: How many component tests should you write vs end-to-end tests or lower-level unit tests? How can you test a certain line of code that is tricky to test? And what in the world are you supposed to do about that persistent act() warning?
In this three-hour workshop we’ll introduce React Testing Library along with a mental model for how to think about designing your component tests. This mental model will help you see how to test each bit of logic, whether or not to mock dependencies, and will help improve the design of your components. You’ll walk away with the tools, techniques, and principles you need to implement low-cost, high-value component tests.
Table of contents- The different kinds of React application tests, and where component tests fit in- A mental model for thinking about the inputs and outputs of the components you test- Options for selecting DOM elements to verify and interact with them- The value of mocks and why they shouldn’t be avoided- The challenges with asynchrony in RTL tests and how to handle them
Prerequisites- Familiarity with building applications with React- Basic experience writing automated tests with Jest or another unit testing framework- You do not need any experience with React Testing Library- Machine setup: Node LTS, Yarn

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

A Guide to React Rendering Behavior
React Advanced Conference 2022React Advanced Conference 2022
25 min
A Guide to React Rendering Behavior
Top Content
React is a library for "rendering" UI from components, but many users find themselves confused about how React rendering actually works. What do terms like "rendering", "reconciliation", "Fibers", and "committing" actually mean? When do renders happen? How does Context affect rendering, and how do libraries like Redux cause updates? In this talk, we'll clear up the confusion and provide a solid foundation for understanding when, why, and how React renders. We'll look at: - What "rendering" actually is - How React queues renders and the standard rendering behavior - How keys and component types are used in rendering - Techniques for optimizing render performance - How context usage affects rendering behavior| - How external libraries tie into React rendering
Building Better Websites with Remix
React Summit Remote Edition 2021React Summit Remote Edition 2021
33 min
Building Better Websites with Remix
Top Content
Remix is a new web framework from the creators of React Router that helps you build better, faster websites through a solid understanding of web fundamentals. Remix takes care of the heavy lifting like server rendering, code splitting, prefetching, and navigation and leaves you with the fun part: building something awesome!
React Compiler - Understanding Idiomatic React (React Forget)
React Advanced Conference 2023React Advanced Conference 2023
33 min
React Compiler - Understanding Idiomatic React (React Forget)
Top Content
React provides a contract to developers- uphold certain rules, and React can efficiently and correctly update the UI. In this talk we'll explore these rules in depth, understanding the reasoning behind them and how they unlock new directions such as automatic memoization. 
Using useEffect Effectively
React Advanced Conference 2022React Advanced Conference 2022
30 min
Using useEffect Effectively
Top Content
Can useEffect affect your codebase negatively? From fetching data to fighting with imperative APIs, side effects are one of the biggest sources of frustration in web app development. And let’s be honest, putting everything in useEffect hooks doesn’t help much. In this talk, we'll demystify the useEffect hook and get a better understanding of when (and when not) to use it, as well as discover how declarative effects can make effect management more maintainable in even the most complex React apps.
Routing in React 18 and Beyond
React Summit 2022React Summit 2022
20 min
Routing in React 18 and Beyond
Top Content
Concurrent React and Server Components are changing the way we think about routing, rendering, and fetching in web applications. Next.js recently shared part of its vision to help developers adopt these new React features and take advantage of the benefits they unlock.In this talk, we’ll explore the past, present and future of routing in front-end applications and discuss how new features in React and Next.js can help us architect more performant and feature-rich applications.
(Easier) Interactive Data Visualization in React
React Advanced Conference 2021React Advanced Conference 2021
27 min
(Easier) Interactive Data Visualization in React
Top Content
If you’re building a dashboard, analytics platform, or any web app where you need to give your users insight into their data, you need beautiful, custom, interactive data visualizations in your React app. But building visualizations hand with a low-level library like D3 can be a huge headache, involving lots of wheel-reinventing. In this talk, we’ll see how data viz development can get so much easier thanks to tools like Plot, a high-level dataviz library for quick & easy charting, and Observable, a reactive dataviz prototyping environment, both from the creator of D3. Through live coding examples we’ll explore how React refs let us delegate DOM manipulation for our data visualizations, and how Observable’s embedding functionality lets us easily repurpose community-built visualizations for our own data & use cases. By the end of this talk we’ll know how to get a beautiful, customized, interactive data visualization into our apps with a fraction of the time & effort!