CZEMacLeod / MSBuild.SDK.SystemWeb

This MSBuild SDK is designed to allow for the easy creation and use of SDK (shortform) projects targeting ASP.NET 4.x using System.Web.
MIT License
151 stars 8 forks source link

Visual Studio 2019 (v16.9.4) becomes unresponsive when marking MVC views as content when the Views directory contains a large number of files #10

Closed stevenvolckaert closed 2 years ago

stevenvolckaert commented 3 years ago

Hello!

I've been using MSBuild.SDK.SystemWeb v4.0.47 in one of our ASP.NET projects running in .NET Framework 4.8, and although I had to mark the ~/Views, ~/Content, and ~/Scripts directories as Content, the migration to the SDK-style project format was successful.

I have another project which contains a very large amount of MVC views in the ~/Views directory; the csproj is now around 20.000 lines long and around 2 MiB in size.

I have a team of 6 to 8 people working in this project on a daily basis. Because of the large file size of the csproj, and the fact that it changes so frequently (usually around 10 times per day - that means around 10 commits per day that change this file), I've decided to track this file in Git LFS.

Because of the frequent changes, we constantly get merge conflicts which need to be resolved manually.

Merging the Git LFS tracked csproj file has worked in the past, but since me and some of my team members upgraded to Visual Studio v16.9 (I currently run v16.9.4), the Visual Studio merge tool doesn't download the Git LFS file prior to opening the merge tool. This means we only see the pointers to the Git LFS tracked files in the merge tool, not the file's content itself.

So, I wanted to solve this problem by migrating to SDK-style project format. After that, merge conflicts should be rare (because of the file globbing capabilities).

The migration works, but... I need to mark a list of files as content, otherwise my MSBuild command used to publish the project (for deployment), doesn't include the files in the publish output.

So I added the following to my csproj:

  <ItemGroup>
    <ContentFiles Include="App_Code\**;Content\**;Scripts\**;_app_offline.htm;appsettings.json;engineConfiguration.config;Global.asax;NLog.config;robots.txt" />
    <ViewFiles Include="Views\**" />
    <None Remove="@(ContentFiles)" />
    <None Remove="@(ViewFiles)" />
    <Content Include="@(ContentFiles)" />
    <Content Include="@(ViewFiles)" />
  </ItemGroup>

When I added this to the csproj and load the project, Visual Studio 2019 becomes unresponsive. I guess this is because of the very large amount of files it is recursively iterating. Unfortunately, this is unworkable for my team.

Perhaps I can mark these files as content in a different way? Maybe you have some ideas?

Many thanks in advance for your help!!

Steven Volckaert

bachratyg commented 3 years ago

You should try using globs directly instead of @(Items) when moving items from None to Content and refrain from using Remove whenever possible. That tends to be much faster at the cost of your project being a bit more verbose.

There is an issue with VS because internally globs are turned into regexes and that prevents short-circuiting of directory traversals (e.g. Views\** glob is matched against all files in node_modules\** even though the prefix is guaranteed to fail). AFAIK this will ship in VS 16.10. See https://github.com/dotnet/msbuild/issues/2000

You can also try setting EnableDefaultNoneItems to false, then you can simplify your project to this:

  <PropertyGroup>
    <EnableDefaultNoneItems>false</EnableDefaultNoneItems>
  </PropertyGroup>
  <ItemGroup>
    <Content Include="App_Code\**;Content\**;Scripts\**;_app_offline.htm;appsettings.json;engineConfiguration.config;Global.asax;NLog.config;robots.txt" />
    <Content Include="Views\**" />
  </ItemGroup>

This has the side effect that by default no items will be added as None and you have to add them manually.

Note that this sdk is still very much a work in progress and may not support all features that the first-party sdks do (e.g. DefaultItemExcludes is not honored in some cases).

stevenvolckaert commented 3 years ago

Thank you so much for your suggestions @bachratyg! I'll try them out and report back here.

stevenvolckaert commented 2 years ago

I got this working several weeks ago, and none of my team members reported issues. Thank you @bachratyg for your help!