Skip to content

MSBuild integration with ASP.NET Core #60538

Open
@javiercn

Description

@javiercn

The ASP.NET SDK has an asset pipeline that processes all the web content for the app to apply optimizations (compression/fingerprinting, etc.).

There are a few things that make integration between the MSBuild SDK and the ASP.NET Core pipeline challenging, and while we've given people guidance, it would be great if we can enable this scenario to work without having to make such changes to their project.

There are two main challenges that we face:

  • By default the TypeScript targets run too late in the pipeline for us to see the generated outputs. Our guidance suggests hooking up the relevant targets to the PrepareForBuild target as shown below:
<PrepareForBuildDependsOn>
  CompileTypeScript;
  CompileTypeScriptWithTSConfig;
  GetTypeScriptOutputForPublishing;$(PrepareForBuildDependsOn)
</PrepareForBuildDependsOn>
  • I suspect the snippet above is not fully correct, as more targets are involved in the TypeScript setup in CompileDependsOn.
  • This makes the TS targets run early enough so that standard targets in the ASP.NET Core pipeline can detect and process them as expected.
  • The second challenge that we face is that is typical for people to dump their outputs into the wwwroot folder. When this happens, (after the change above) GetTypeScriptOutputForPublishing will add all the GeneratedJavaScript items to the Content item group unconditionally.
    • This results in the presence of duplicate Content items that interferes with the build.
    • We've given people the following target to remove the duplicates before the GetTypeScriptOutputForPublishing target adds them.
    <Target Name="RemoveDuplicateTypeScriptOutputs" BeforeTargets="GetTypeScriptOutputForPublishing">
      <ItemGroup>
        <Content Remove="@(GeneratedJavaScript)" />
      </ItemGroup>
    </Target>

This gets things into a working state, but it's obviously not trivial for customers to discover/setup in their app. Hopefully we can work together to make this scenario just work by implementing a few simple changes.

  • Have a target ResolveTypeScriptOutputs or similar that produces the compile outputs as items in the Content item group and that can run early enough in the pipeline (PrepareForBuild is a good candidate, or it can be configurable).
  • Avoid adding duplicate content items to the Content item group by using Exclude="@(Content) to prevent duplicates.
  • Checking for UsingMicrosoftNETSdkStaticWebAssets to wire up ResolveTypeScriptOutputs early enough in the pipeline so that the outputs can be detected and disable other targets that are not needed (Anything that deals with copying the outputs to the output/publish folder is already handled by the static web assets SDK).

Activity

self-assigned this
on Nov 20, 2024
JeroMiya

JeroMiya commented on Dec 26, 2024

@JeroMiya

Just adding a related issue with the PrepareForBuildDependsOn element: this element is suggested in the documentation, but adding it causes the PreComputeCompileTypeScriptWithTSConfig task to be skipped, because it can't find tsconfig.json file in the content files list at that stage in the build perhaps? I've verified the tsconfig.json file is marked as Content (it's marked so by default), and PreComputeCompileTypeScriptWithTSConfig task is NOT skipped when the PrepareForBuildDependsOn element is removed. So, as far as I can tell, there is no way to use Microsoft.TypeScript.MSBuild with a tsconfig.json in the current implementation. Additionally, without adding the PrepareForBuildDependsOn, in .net 9 SDK, it appears the fingerprinting build step errors out and fails (see; dotnet/aspnetcore#58948 which is closed yet is still an issue with no working workaround).

So yeah, this is a critical issue. Hopefully it can get escalated, yeah? It's preventing developers from updating to the latest visual studio/.net sdk.

FreyLuis

FreyLuis commented on Dec 26, 2024

@FreyLuis
JeroMiya

JeroMiya commented on Dec 26, 2024

@JeroMiya

@JeroMiya This works on .net 8:

dotnet/aspnetcore#57662 (comment)

We experienced this issue while attempting to migrate to Microsoft.TypeScript.MSBuild from a custom npm based task to do the frontend build, so the migration will be put on hold until there is an official fix.

boppbo

boppbo commented on Apr 23, 2025

@boppbo

Adding these two workarounds is not enough for me as I get the following error in a blazor webassembly standalone app:
>Microsoft.NET.Sdk.StaticWebAssets.Compression.targets(263,5): Error : The asset '<removed>\obj\Debug\net9.0\compressed\zgut133n0y-5xksfm6j99.gz' can not be found at any of the searched locations 'wwwroot\js\base.js' and '<removed>\wwwroot\js\base.js'.

I fixed this error by setting <DisableBuildCompression>true</DisableBuildCompression>

Edit: Sometimes my .js output files were deleted during rebuild.

1TT-Chris

1TT-Chris commented on May 15, 2025

@1TT-Chris

After much fiddling, in my .Net8 Blazor Web App project, I found I needed to add FindConfigFiles to PrepareForBuildDependsOn to pick up tsconfig files. And the RemoveDuplicateTypeScriptOutputs needed to use AfterTargets rather than BeforeTargets.

<Target Name="FixTypescriptCompileDependencies" BeforeTargets="BeforeBuild">
  <PropertyGroup>
    <PrepareForBuildDependsOn>
      FindConfigFiles;
      CompileTypeScript;
      CompileTypeScriptWithTSConfig;
      GetTypeScriptOutputForPublishing;
      $(PrepareForBuildDependsOn)
    </PrepareForBuildDependsOn>
  </PropertyGroup>
</Target>

<Target Name="RemoveDuplicateTypeScriptOutputs" AfterTargets="GetTypeScriptOutputForPublishing">
  <Message Importance="High" Text="GeneratedJavaScript files are: @(GeneratedJavaScript)" />
  <ItemGroup>
    <Content Remove="@(GeneratedJavaScript)" />
  </ItemGroup>
</Target>
glatzert

glatzert commented on Jun 4, 2025

@glatzert

We just stumbled over this problem in a Razor Class Library and it's rather annoying, that TS isn't a first class citizen there - could you guys talk to the dotnet guys and figure out, how to properly include TS in RCL and other dotnet things like Blazor?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Needs InvestigationThis issue needs a team member to investigate its status.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @JeroMiya@boppbo@joj@RyanCavanaugh@javiercn

      Issue actions

        MSBuild integration with ASP.NET Core · Issue #60538 · microsoft/TypeScript