Only Build What Changed with Nx Affected Commands

Share this video with your friends

Send Tweet
Published 3 months ago
Updated 2 months ago

If you work in a monorepo you want to make sure to have tooling that supports that. Nx comes with those baked in, allowing you to grow your monorepo from a single to multiple apps. One way Nx tackles this is by providing so-called affected commands.

Prefer to read along as well? Here's the accompanying article.

Instructor: [0:00] Once our Nx workspace grows with, potentially, multiple applications in here, as well as hundreds of libraries, we definitely want to make sure to not waste any computation power, and also optimize for speed. Behind the scenes, Nx has the so-called dep graph, which you can invoke by nx dep-graph. That, basically, has a visualization of everything that is inside our workspace.

[0:23] For instance, Nx knows about the end-to-end projects that have been generated for our libraries and applications. It knows about our site project, it knows about the shared-ui, as well as the libraries here, shared-mdx-elements and Markdown.

[0:36] Based on this dependency graph, Nx makes decisions behind the scenes on what to execute via the so-called Effect commands. Let's explore this by, first of all, creating a new React application. I'm creating here a new React application with the generator again. Now we have such a React application. Again, if we execute the dependency graph, we can now see that Nx is also aware about that React application, which it hasn't connected yet to any library.

[1:07] Let's see what happens if React app also imports shared-ui. Let's go into our App.tsx component, and just for the sake of this example, import from yuri/dev/shared-ui, and let me import here the Topic button, for instance. Let's include the Topic button somewhere here, and then let's again show the dependency graph.

[1:33] If we now have a look, it clearly understands that the React application has such a shared-ui dependency, as well as our site. Shared-ui becomes a shared dependency between both of these applications. Let's assume this is the current state. Let's comment this, and then let's create a new branch, My Feature.

[1:54] Assuming this feature branch, we are actually just going to make a change in our Markdown library. Let me open up that Markdown file, and let's do nothing else than adding here a console.log. Let me add this change. Let's, again, use the dependency graph, but this time, let's use the so-called Affected command for it. We use, affected dep-graph, and as the base, we give it the previous branch.

[2:21] The previous branch, in our case, is not the master or main one, which would be a normal development scenario. Since we are developing this course repository, the previous branch is 25-export-nextjs-site.

[2:34] Let me just link that as the previous branch, and now hit Enter. This will give us now the visualization of what nodes have been affected by the changes in this branch, compared to its base.

[2:46] Now, since the base is basically our 25-export-nextjs-site, in the meantime, the only thing we changed was that console.log in a Markdown library.

[2:56] As a matter of the results, since Nx has the complete vision of the entire dependency graph in our workspace, it is able to figure out that the only things that are affected by this change is the Site project, which is our Next.js application, as well as its end-to-end tests.

[3:11] In fact, if we Select All, we can see that this path here is colored in a different way than all the other applications and libraries in our repository. As such, what we can do, is we can not only visualize this as a dependency graph, but we can execute the targets against these affected commands. We can use, for instance, the Build command, and only build what has been affected.

[3:35] Nx correctly figures out that the only build targets within our workspace is the React application, as well as the Site Next.js application, and so it only builds those two. In this case, the React application has not been affected by the change, and so only Site would be rebuilt.

[3:51] This can dramatically speed up, obviously, the build times or test execution times you might have within a monorepo, because we only build or test or lint, a subset of the changes that would otherwise be necessary.