🍒 Cherry-Picked Nx v19.6 Updates
🌊 Nx Core
Skipping Dependent Tasks
When testing or for any other reason, you may want to skip running the entire tree of task dependencies. You can now achieve this with the --exclude-task-dependencies
flag in your Nx command:
nx run app:build --exclude-task-dependencies
New Nx Sync Command
⚠️ This is an experimental feature, currently undocumented and subject to change.
The nx sync
command is a new feature that runs a list of generators to ensure your workspace is always up-to-date:
nx sync
You can configure this command globally in your nx.json
:
{
sync: {
/**
* List of workspace-wide sync generators to be run (not attached to targets).
*/
globalGenerators?: string[];
/**
* Options for the sync generators.
*/
generatorOptions?: {
[generatorName: string]: Record<string, unknown>;
};
/**
* Whether to automatically apply sync generator changes when running tasks.
* If not set, the user will be prompted.
* If set to `true`, the user will not be prompted and the changes will be applied.
* If set to `false`, the user will not be prompted and the changes will not be applied.
*/
applyChanges?: boolean;
}
}
Alternatively, you can configure it per target by adding the syncGenerators
option to the target’s configuration. For example:
"libs/my-lib": {
"targets": {
"typecheck": {
"command": "tsc --build --emitDeclarationOnly --pretty --verbose",
"outputs": [],
"syncGenerators": [
"@nx/js:typescript-sync",
],
},
},
},
In this setup, the @nx/js:typescript-sync
generator will be called before running the TypeScript command to keep tsconfig
project references in sync with the project graph.
You can also run nx sync:check
to validate that the workspace is up-to-date without applying changes. This is especially useful as a CI validation step.
New Nx Import Command
Nx has introduced a new command to simplify integrating external repositories into your monorepo:
nx import
Transferring files between repos can be tricky, especially when preserving Git history. The nx import
command automates the process by:
Cloning the external repository.
Moving the code to the desired directory in a temporary branch.
Merging the code into the current workspace branch.
Recommending Nx plugins for tool integration from the imported code.
For a demo of how nx import
works, check out this PR demo:
🧩 Module Federation
New setRemoteDefinition API
Instead of using setRemoteDefinitions
, which replaces the entire state, you can now use setRemoteDefinition(remoteName: string, remoteUrl: string)
to add or update a specific remote without overwriting the existing remote map.
Local DX Improvements
I will redirect you to the new great documentation: Nx Module Federation Technical Overview:
The NxRuntimeLibraryControlPlugin
Previously, when using shared workspace libraries as part of your Module Federation application, there was a chance that the workspace library would be provided by one of the static remotes
. This would cause issues where changes to those shared libraries would not be reflected in the locally served application.
To combat this issue, we developed the NxRuntimeLibraryControlPlugin
. This is a Runtime Plugin that will ensure that workspace libraries are only shared via any active dev remote
. This means that any changes to the shared library will be picked up by webpack-dev-server
and, as such, reflected in the locally served application.
This plugin is enabled by default, however, you can turn it off in your module-federation.config
file:
export const config: ModuleFederationConfig = {
...,
disableNxRuntimeLibraryControlPlugin: true
}
📦 Nx Release
Version Plans
Nx Release is introducing a new approach to versioning packages. Until now, Nx Release supported either a static approach — prompting for each project — or an automatic approach based on conventional commits from Git history.
However, if you’re not using conventional commits or prefer to have more control over the release notes and how versions are bumped, you can now use the new Version Plan approach. With this method, version bumps are defined by files located in the .nx/version-plans
folder.
Let’s walk through an example using the e2e version-plans.test.ts
. Imagine you have two groups of releases: one group with a fixed version (fixed-group
) and another with independent versions (independent-group
). You can configure nx.json
to activate your version plans as follows:
{
"release": {
"groups": {
"fixed-group": {
"projects": ["pkg1", "pkg2"],
"releaseTagPattern": "v{version}"
},
"independent-group": {
"projects": ["pkg3", "pkg4", "pkg5"],
"projectsRelationship": "independent",
"releaseTagPattern": "{projectName}@{version}"
},
},
"version": {
"generatorOptions": {
"specifierSource": "version-plans"
},
},
"changelog": {
"projectChangelogs": true,
},
"versionPlans": true,
};
}
Next, you can create a Version Plan file to specify how to bump the versions for each package and group.
You can either generate it automatically by running:
nx release plan minor -g fixed-group -m "feat: Update the fixed packages with a minor release."
Or, you can create one manually by adding a file like ./nx/bump-independent.md
:
---
pkg3: patch
pkg4: preminor
pkg5: prerelease
---
feat: Update the independent packages with a patch, preminor, and prerelease.
Once these plans are defined and pushed, the nx release
command will follow them:
pkg1 📄 Resolved the specifier as "minor" using version plans.
...
pkg2 ✍️ New version 0.1.0 written to pkg2/package.json
...
pkg3 📄 Resolved the specifier as "patch" using version plans.
pkg4 📄 Resolved the specifier as "preminor" using version plans.
pkg5 📄 Resolved the specifier as "prerelease" using version plans.
The changelog will not only be generated from the Git commits but will also include details from your Version Plan.
To ensure every modification impacting a releasable project aligns with a version plan, you can run the following on your CI:
nx release plan:check
For more information, see the blog post Nx 19.5 is here! Stackblitz, Bun, Incremental Builds for Vite, Gradle Test Atomizer
Log Unchanged Project Only
The version generator logs activity for every project, which can create noise in large monorepos where only a subset of projects is being released.
To address this, a new logUnchangedProjects
option has been introduced. This allows you to configure the generator to suppress logs for unchanged projects. The default behavior remains unchanged, and this option is opt-in.
🌐 Nx Cloud
Explain with AI
Following the introduction of AI into Nx’s documentation (via AI Chat) and Nx Cloud (via Tusky), a new Explain With AI feature is now available. This tool helps developers quickly understand complex errors and provides suggestions for improvements, streamlining the debugging process.
💫 Upgrades
Support of Angular v18.2.0
Support Storybook 8
Upgrade to Jest v29.7.0
📣 Monorepo World Conference
The Monorepo World conference is coming up soon on October 7, 2024 at the Computer History museum in Mountain View, California.
Looking for some help? 🤝Connect with me on Twitter • LinkedIn • Github
Subscribe to my newsletter
Read articles from Jonathan Gelin directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Jonathan Gelin
Jonathan Gelin
Who am I? Whether it's as a Software Engineer, Tech Lead, or Architect, if it involves software development, I'm in! My journey began in the realm of Java development, but I fully transitioned into the universe of JavaScript/TypeScript and its exciting toolset. I support companies through their software development cycle challenges by utilizing Nx monorepos, micro frontends, robust testing strategies, and a touch of Extreme Programming philosophy. Every day for me is like waiting for the next episode of my favorite series—filled with learning, sharing, and growing together. Indeed, I'm as passionate about coaching and sharing knowledge as I am about coding. I am the father of two incredible boys, and I am endlessly grateful to my wife for supporting my passion every day.