Feedback & Suggestions for the new @nx/dotnet plugin #35837
TobiDimmel
started this conversation in
Feature Requests
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
I really appreciate that the Nx team decided to officially support .NET with the new experimental
@nx/dotnetplugin. I mainly work in a .NET/Angular Nx workspace and recently migrated from the old@nx-dotnet/corecommunity plugin.Now I want to share my experience and some thoughts on improvement because my migration had a few hurdles. My thoughts range from simple to more challenging and fundamental problems. I will try to propose some possible solutions to the best of my knowledge.
Communication of experimental status
Unfortunately, the experimental status of the plugin is not well communicated. The only place where you can see it is on the technology introduction page.
But my migration journey started from a different entry point. The page of the old community plugin shows a popup stating that it is deprecated and a new official plugin is available. There is no mention that the new plugin is still experimental, and it directly links to the migration guide on nx.dev, which also has no hint regarding its experimental status. It was only later, in the middle of my migration, that I realized it is still experimental.
Even in the Nx v22 release blog post, there is no word about the experimental status. The subheadline for the plugin even says Enterprise-ready. Interestingly, the Maven plugin is declared experimental in that same blog post.
I created an issue (#34844) to update at least the migration guide with an experimental status warning. In general, I hope this will be communicated more prominently in future release blog posts.
Dependency on specific configurations
After migrating, the first confusing part was that there is a
buildand abuild:releaseinferred target. Besides the fact that thebuild:releasetarget isn't documented anywhere, it is even more confusing that both targets have aDebugand aReleaseconfiguration. I think the idea is to be able to define a dependency on aReleasebuild in thepublishtarget, because you always want to publish the release version. But then there is again aDebugand aReleaseconfiguration in thepublishtarget, which doesn't make sense from my point of view.The fundamental problem here is that an Nx target can't depend on a specific configuration of another target. The
TargetDependencyConfighas no property for this scenario.I see two possible approaches to this problem:
TargetDependencyConfigto specify a configuration.build:releasetarget and remove theDebugandReleaseconfigurations completely.The first approach could have wider consequences for the Nx ecosystem. Also, I couldn't say how Nx should behave if you run a target with one configuration while it depends on a target with a different configuration. This would interfere with the configuration forwarding of Nx. However, this approach would map .NET configurations to corresponding Nx configurations more intuitively.
The second approach, on the other hand, has the disadvantage that defining multiple targets instead of configurations is not the usual Nx way of doing things.
A rather minor problem is the use of
:as a delimiter in the target name. If you want to runMyApi:build:release, Nx understandably responds with the warningAmbiguous target specifier "MyApi:build:release"and selects the most specific match. Since thebuild:releasetarget is always inferred in alignment with thebuildtarget, this has no practical negative effect, but it is strange behavior for an official plugin. Using a different delimiter like-would make this workaround more explicit and therefore easier to understand in other places (e.g., in thedependsOnarray of thepublishtarget).Renaming of configurations
Since I work in a .NET/Angular workspace, I want to have a consistent naming convention for the configurations of my targets. In the Angular world, it is more common to name configurations
developmentandproductioninstead ofDebugandRelease.Therefore, I suggest introducing a plugin configuration option to rename the generated configurations, similar to how it is already possible with target names.
Different output paths
By default, .NET uses different output paths inside the
binandobjfolders depending on the used .NET configuration, target framework, and runtime identifier (if specified). These values can be manipulated via project files,Directory.Build.propsfiles, and .NET CLI parameters.With Nx, you can only define outputs at the target level. This mismatch is solved for the
buildandbuild:releasetargets by defining the entirebinandobjfolders as outputs. While this is not ideal because unrelated build artifacts are potentially cached, it should be sufficient in practice.Unfortunately, this isn't true for the
publishtarget. There, the actual publish directory is defined as the output, which depends on the concrete .NET execution. Hence, the publish output is not cached correctly as soon as you use different Nx configurations with different .NET CLI parameters, or pass different .NET CLI parameters directly during execution.Besides the caching problem, using more specific .NET CLI parameters on the
publishtarget is currently not working because they are not propagated to thebuild:releasetarget. However, there is already an issue and a PR tracking this (#33474, #33662).In my migration journey, I came from a publish target that looked like this:
Since the migration wasn't straightforward due to the problems discussed above, I ended up setting
<RuntimeIdentifier>win-x64</RuntimeIdentifier>inside each of my projects as a workaround. I can easily imagine that this workaround isn't feasible for everyone. My struggle with these problems ultimately prompted me to write this post.I suggest the following improvements to tackle these issues:
binandobjfolders as outputs for thepublishtarget by default.--output.NET CLI parameter.As a side note, I don't use
dotnet packin my workspace, so I can't say if thepacktarget suffers from similar problems aspublish.Restoring
Another aspect I struggled with was restoring my projects, since this isn't done by the plugin and automatic restores are suppressed via
--no-restore. I develop my .NET projects with Visual Studio, which restores projects automatically. The .NET CLI also does this transparently by default. As a result, I wasn't used to worrying much about restoring until this migration.In a clean workspace without Visual Studio open, you have to restore manually before running any other Nx targets. Unfortunately, this isn't well documented. The only hint I found is an info box in the "Incremental builds" guide:
To smoothen the onboarding process, I suggest explaining this topic more prominently on the introduction page of the documentation so that everyone knows how to set up their environment for automatic restoring or how to restore manually.
Furthermore, I have a few questions regarding the cited info box:
watchtarget depend onrestoreif the statement is true?restoretarget at all if the statement is true? Wouldn't runningnx run-many -t restore buildbe problematic?Closing thoughts
I hope I was able to clearly explain my struggles with the current state of the experimental
@nx/dotnetplugin to help initiate improvements for a better developer experience.Did you struggle with the same or other problems?
What do you think about my propositions?
I'm very interested in your experiences and opinions.
@AgentEnder Let me know if I can be of any help.
All reactions