-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add TypeScript Static Web Assets integration #52302
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Fixes #51822 This commit adds support for integrating TypeScript outputs from the Microsoft.TypeScript.MSBuild NuGet package with ASP.NET Core Static Web Assets in Razor Class Libraries. ## Problem When using TypeScript with Static Web Assets in RCLs, rebuild operations fail because: 1. TypeScript compilation runs during the Compile phase, AFTER Static Web Assets discovery has already occurred 2. During Clean, TypeScript targets delete the .js files, but Content items (added by Razor SDK globbing) persist in memory 3. DefineStaticWebAssets then fails because it finds Content items referencing files that no longer exist ## Solution Added Microsoft.NET.Sdk.StaticWebAssets.TypeScript.targets which: - Hooks into ResolveStaticWebAssetsInputsDependsOn to register TypeScript outputs AFTER compilation - Removes TypeScript outputs from Content before CoreClean and ResolveProjectStaticWebAssets to prevent stale item references - Uses DefineStaticWebAssets/DefineStaticWebAssetEndpoints for proper integration with compression, fingerprinting, and manifest generation - Creates a manifest file (staticwebassets.typescript.files.txt) to track registered assets across builds ## Changes - Added Microsoft.NET.Sdk.StaticWebAssets.TypeScript.targets - Added conditional import in main targets when TypeScript package is detected - Added TypeScriptIntegrationTest.cs with 8 E2E tests - Added Microsoft.TypeScript.MSBuild to central package management
src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.TypeScript.targets
Outdated
Show resolved
Hide resolved
| <!-- | ||
| Target: ResolveTypeScriptStaticWebAssetsConfiguration | ||
|
|
||
| Sets up the path for the TypeScript manifest file. | ||
| DependsOnTargets ResolveStaticWebAssetsConfiguration to ensure | ||
| _StaticWebAssetsManifestBase is defined. | ||
| --> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| <!-- | |
| Target: ResolveTypeScriptStaticWebAssetsConfiguration | |
| Sets up the path for the TypeScript manifest file. | |
| DependsOnTargets ResolveStaticWebAssetsConfiguration to ensure | |
| _StaticWebAssetsManifestBase is defined. | |
| --> |
src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.TypeScript.targets
Outdated
Show resolved
Hide resolved
| <PropertyGroup> | ||
| <ResolveStaticWebAssetsInputsDependsOn> | ||
| RegisterTypeScriptStaticWebAssets; | ||
| $(ResolveStaticWebAssetsInputsDependsOn) | ||
| </ResolveStaticWebAssetsInputsDependsOn> | ||
| </PropertyGroup> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this before the target definitions
src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.TypeScript.targets
Outdated
Show resolved
Hide resolved
| <!-- | ||
| Write manifest file to track registered assets across builds. | ||
| WriteOnlyWhenDifferent prevents unnecessary timestamp changes for incremental builds. | ||
| FileWrites ensures the manifest is cleaned up during Clean target. | ||
| --> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| <!-- | |
| Write manifest file to track registered assets across builds. | |
| WriteOnlyWhenDifferent prevents unnecessary timestamp changes for incremental builds. | |
| FileWrites ensures the manifest is cleaned up during Clean target. | |
| --> |
src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.TypeScript.targets
Outdated
Show resolved
Hide resolved
| <!-- | ||
| Define endpoints for TypeScript assets. | ||
| This creates the endpoint entries that map URL paths to assets, | ||
| which are needed for the runtime to serve the files correctly. | ||
| --> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| <!-- | |
| Define endpoints for TypeScript assets. | |
| This creates the endpoint entries that map URL paths to assets, | |
| which are needed for the runtime to serve the files correctly. | |
| --> |
src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.TypeScript.targets
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds TypeScript Static Web Assets integration for Razor Class Libraries to fix rebuild failures when using the Microsoft.TypeScript.MSBuild NuGet package. The solution introduces a new targets file that properly registers TypeScript-compiled JavaScript outputs as static web assets after compilation completes.
Key Changes:
- Introduces
RegisterTypeScriptStaticWebAssetstarget that hooks into the Static Web Assets pipeline to register TypeScript outputs after compilation - Implements
RemoveTypeScriptFromContentBeforeSwaDiscoveryto prevent stale Content item references during rebuild operations - Adds comprehensive E2E test coverage with 8 integration tests covering build, rebuild, clean, publish, and incremental build scenarios
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
Microsoft.NET.Sdk.StaticWebAssets.TypeScript.targets |
New targets file implementing TypeScript/SWA integration with manifest tracking and proper cleanup |
Microsoft.NET.Sdk.StaticWebAssets.targets |
Conditional import of TypeScript targets when TypeScript package is detected |
TypeScriptIntegrationTest.cs |
Comprehensive test suite with 8 tests covering all key scenarios |
Microsoft.NET.Sdk.StaticWebAssets.Tests.csproj |
Assembly metadata for TypeScript package version configuration |
Versions.props |
TypeScript MSBuild package version definition (5.9.3) |
Directory.Packages.props |
Package version reference for central package management |
src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.TypeScript.targets
Show resolved
Hide resolved
test/Microsoft.NET.Sdk.StaticWebAssets.Tests/TypeScriptIntegrationTest.cs
Outdated
Show resolved
Hide resolved
…tionTest.cs Co-authored-by: Copilot <[email protected]>
MackinnonBuck
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, just a small question about a test.
| // Wait a bit and do incremental build | ||
| await Task.Delay(100); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed? Does the test become flaky without it? Is there another way we can detect when the right conditions are met for the test to continue?
Summary
Fixes #51822, #52301
This PR adds support for integrating TypeScript outputs from the
Microsoft.TypeScript.MSBuildNuGet package with ASP.NET Core Static Web Assets in Razor Class Libraries.Problem
When using TypeScript with Static Web Assets in RCLs, rebuild operations fail because:
.jsfiles, butContentitems (added by Razor SDK globbing) persist in memoryDefineStaticWebAssetsthen fails because it findsContentitems referencing files that no longer existSolution
Added
Microsoft.NET.Sdk.StaticWebAssets.TypeScript.targetswhich:ResolveStaticWebAssetsInputsDependsOnto register TypeScript outputs AFTER compilationContentbeforeCoreCleanandResolveProjectStaticWebAssetsto prevent stale item referencesDefineStaticWebAssets/DefineStaticWebAssetEndpointsfor proper integration with compression, fingerprinting, and manifest generationstaticwebassets.typescript.files.txt) to track registered assets across buildsChanges
Microsoft.NET.Sdk.StaticWebAssets.TypeScript.targetsMicrosoft.NET.Sdk.StaticWebAssets.targetsTypeScriptIntegrationTest.csMicrosoft.NET.Sdk.StaticWebAssets.Tests.csprojeng/Versions.propsMicrosoftTypeScriptMSBuildPackageVersionDirectory.Packages.propsMicrosoft.TypeScript.MSBuildpackage referenceTest Coverage
All 8 integration tests pass:
Build_RegistersTypeScriptOutputsAsStaticWebAssetsBuild_TypeScriptOutputsAreProperlyCompressedRebuild_SucceedsWithTypeScriptOutputs(main scenario from InvalidOperationException REBUILD fails due to "no file exists for the asset at either location" BUILD works #51822)Build_IncrementalBuild_WorksCorrectlyBuild_ModifyTypeScriptFile_UpdatesStaticWebAssetsPublish_IncludesTypeScriptOutputsClean_ThenBuild_SucceedsWithTypeScriptOutputsBuild_TypeScriptDisabled_DoesNotRegisterAssetsHow It Works
During rebuild, the
RemoveTypeScriptFromContentBeforeSwaDiscoverytarget runs beforeCoreCleanto prevent stale Content item references.