diff --git a/src/Components/WebAssembly/Sdk/integrationtests/WasmPublishIntegrationTest.cs b/src/Components/WebAssembly/Sdk/integrationtests/WasmPublishIntegrationTest.cs
index 7e14ca0936c6..0ad730be1b94 100644
--- a/src/Components/WebAssembly/Sdk/integrationtests/WasmPublishIntegrationTest.cs
+++ b/src/Components/WebAssembly/Sdk/integrationtests/WasmPublishIntegrationTest.cs
@@ -970,6 +970,58 @@ public async Task Publish_WithInvariantGlobalizationEnabled_DoesNotCopyGlobaliza
Assert.FileDoesNotExist(result, publishOutputDirectory, "wwwroot", "_framework", "icudt_no_CJK.dat");
}
+ [Fact]
+ public async Task Publish_HostingMultipleBlazorWebApps_Works()
+ {
+ // Regression test for https://github.com/dotnet/aspnetcore/issues/29264
+ // Arrange
+ using var project = ProjectDirectory.Create("BlazorMultipleApps.Server", "BlazorMultipleApps.FirstClient", "BlazorMultipleApps.SecondClient", "BlazorMultipleApps.Shared");
+ var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish");
+
+ var publishOutputDirectory = project.PublishOutputDirectory;
+
+ Assert.FileExists(result, Path.Combine(publishOutputDirectory, "BlazorMultipleApps.Server.dll"));
+ Assert.FileExists(result, Path.Combine(publishOutputDirectory, "BlazorMultipleApps.FirstClient.dll"));
+ Assert.FileExists(result, Path.Combine(publishOutputDirectory, "BlazorMultipleApps.SecondClient.dll"));
+
+ var firstAppPublishDirectory = Path.Combine(publishOutputDirectory, "wwwroot", "FirstApp");
+
+ var firstCss = Assert.FileExists(result, Path.Combine(firstAppPublishDirectory, "css", "app.css"));
+ Assert.FileContains(result, firstCss, "/* First app.css */");
+
+ var firstBootJsonPath = Path.Combine(firstAppPublishDirectory, "_framework", "blazor.boot.json");
+ var firstBootJson = ReadBootJsonData(result, firstBootJsonPath);
+
+ // Do a sanity check that the boot json has files.
+ Assert.Contains("System.Text.Json.dll", firstBootJson.resources.assembly.Keys);
+
+ VerifyBootManifestHashes(result, firstAppPublishDirectory);
+
+ // Verify compression works
+ Assert.FileExists(result, firstAppPublishDirectory, "_framework", "dotnet.wasm.br");
+ Assert.FileExists(result, firstAppPublishDirectory, "_framework", "BlazorMultipleApps.FirstClient.dll.br");
+ Assert.FileExists(result, firstAppPublishDirectory, "_framework", "System.Text.Json.dll.br");
+
+ var secondAppPublishDirectory = Path.Combine(publishOutputDirectory, "wwwroot", "SecondApp");
+
+ var secondCss = Assert.FileExists(result, Path.Combine(secondAppPublishDirectory, "css", "app.css"));
+ Assert.FileContains(result, secondCss, "/* Second app.css */");
+
+ var secondBootJsonPath = Path.Combine(secondAppPublishDirectory, "_framework", "blazor.boot.json");
+ var secondBootJson = ReadBootJsonData(result, secondBootJsonPath);
+
+ // Do a sanity check that the boot json has files.
+ Assert.Contains("System.Private.CoreLib.dll", secondBootJson.resources.assembly.Keys);
+
+ VerifyBootManifestHashes(result, secondAppPublishDirectory);
+
+ // Verify compression works
+ Assert.FileExists(result, secondAppPublishDirectory, "_framework", "dotnet.wasm.br");
+ Assert.FileExists(result, secondAppPublishDirectory, "_framework", "BlazorMultipleApps.SecondClient.dll.br");
+ Assert.FileExists(result, secondAppPublishDirectory, "_framework", "System.Private.CoreLib.dll.br");
+ Assert.FileDoesNotExist(result, secondAppPublishDirectory, "_framework", "System.Text.Json.dll.br");
+ }
+
private static void AddWasmProjectContent(ProjectDirectory project, string content)
{
var path = Path.Combine(project.SolutionPath, "blazorwasm", "blazorwasm.csproj");
@@ -1022,7 +1074,6 @@ static string ParseWebFormattedHash(string webFormattedHash)
}
}
-
private void VerifyTypeGranularTrimming(MSBuildResult result, string blazorPublishDirectory)
{
var componentsShimAssemblyPath = Path.Combine(blazorPublishDirectory, "_framework", "Microsoft.AspNetCore.Razor.Test.ComponentShim.dll");
diff --git a/src/Components/WebAssembly/Sdk/src/targets/Microsoft.NET.Sdk.BlazorWebAssembly.Current.targets b/src/Components/WebAssembly/Sdk/src/targets/Microsoft.NET.Sdk.BlazorWebAssembly.Current.targets
index df0d41cfc17f..514069a7e83e 100644
--- a/src/Components/WebAssembly/Sdk/src/targets/Microsoft.NET.Sdk.BlazorWebAssembly.Current.targets
+++ b/src/Components/WebAssembly/Sdk/src/targets/Microsoft.NET.Sdk.BlazorWebAssembly.Current.targets
@@ -509,7 +509,7 @@ Copyright (c) .NET Foundation. All rights reserved.
<_BlazorPublishBootResource
Include="@(ResolvedFileToPublish)"
- Condition="$([System.String]::Copy('%(RelativePath)').Replace('\','/').StartsWith('wwwroot/_framework')) AND '%(Extension)' != '.a'" />
+ Condition="$([System.String]::Copy('%(RelativePath)').Replace('\','/').StartsWith($(_BlazorFrameworkPublishPath.Replace('\', '/')))) AND '%(Extension)' != '.a'" />
diff --git a/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.FirstClient/App.razor b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.FirstClient/App.razor
new file mode 100644
index 000000000000..28a0c6092098
--- /dev/null
+++ b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.FirstClient/App.razor
@@ -0,0 +1 @@
+@typeof(BlazorMultipleApps.FirstClient.Program)
\ No newline at end of file
diff --git a/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.FirstClient/BlazorMultipleApps.FirstClient.csproj b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.FirstClient/BlazorMultipleApps.FirstClient.csproj
new file mode 100644
index 000000000000..e57b54f6003d
--- /dev/null
+++ b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.FirstClient/BlazorMultipleApps.FirstClient.csproj
@@ -0,0 +1,24 @@
+
+
+
+ net5.0
+ FirstApp
+ $(RazorSdkArtifactsDirectory)$(Configuration)\sdk-output\
+ $(BlazorWebAssemblySdkArtifactsDirectory)$(Configuration)\sdk-output\
+
+
+
+
+
+
+
+
+ $(RepoRoot)artifacts\bin\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib\$(Configuration)\netstandard2.0\
+
+
+
+
+
+
+
+
diff --git a/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.FirstClient/Program.cs b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.FirstClient/Program.cs
new file mode 100644
index 000000000000..be4240805cd7
--- /dev/null
+++ b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.FirstClient/Program.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using System.Text;
+
+namespace BlazorMultipleApps.FirstClient
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ GC.KeepAlive(typeof(System.Text.Json.JsonSerializer));
+ }
+ }
+}
diff --git a/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.FirstClient/wwwroot/css/app.css b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.FirstClient/wwwroot/css/app.css
new file mode 100644
index 000000000000..4855bd609d2d
--- /dev/null
+++ b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.FirstClient/wwwroot/css/app.css
@@ -0,0 +1 @@
+/* First app.css */
\ No newline at end of file
diff --git a/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.FirstClient/wwwroot/index.html b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.FirstClient/wwwroot/index.html
new file mode 100644
index 000000000000..1f450f51fb8a
--- /dev/null
+++ b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.FirstClient/wwwroot/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+ BlazorMultipleApps
+
+
+
+
+
+
+
+
+
diff --git a/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.SecondClient/App.razor b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.SecondClient/App.razor
new file mode 100644
index 000000000000..28e849ebde1f
--- /dev/null
+++ b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.SecondClient/App.razor
@@ -0,0 +1 @@
+@typeof(BlazorMultipleApps.SecondClient.Program)
\ No newline at end of file
diff --git a/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.SecondClient/BlazorMultipleApps.SecondClient.csproj b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.SecondClient/BlazorMultipleApps.SecondClient.csproj
new file mode 100644
index 000000000000..0c38f14b85fb
--- /dev/null
+++ b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.SecondClient/BlazorMultipleApps.SecondClient.csproj
@@ -0,0 +1,24 @@
+
+
+
+ net5.0
+ SecondApp
+ $(RazorSdkArtifactsDirectory)$(Configuration)\sdk-output\
+ $(BlazorWebAssemblySdkArtifactsDirectory)$(Configuration)\sdk-output\
+
+
+
+
+
+
+
+
+ $(RepoRoot)artifacts\bin\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib\$(Configuration)\netstandard2.0\
+
+
+
+
+
+
+
+
diff --git a/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.SecondClient/Program.cs b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.SecondClient/Program.cs
new file mode 100644
index 000000000000..c910511317b0
--- /dev/null
+++ b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.SecondClient/Program.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+
+namespace BlazorMultipleApps.SecondClient
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ }
+ }
+}
diff --git a/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.SecondClient/wwwroot/css/app.css b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.SecondClient/wwwroot/css/app.css
new file mode 100644
index 000000000000..d7cff8ab9dee
--- /dev/null
+++ b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.SecondClient/wwwroot/css/app.css
@@ -0,0 +1 @@
+/* Second app.css */
\ No newline at end of file
diff --git a/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.SecondClient/wwwroot/index.html b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.SecondClient/wwwroot/index.html
new file mode 100644
index 000000000000..bd7f2bbf7754
--- /dev/null
+++ b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.SecondClient/wwwroot/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+ SecondBlazorApp
+
+
+
+
+
+
+
+
+
diff --git a/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.Server/BlazorMultipleApps.Server.csproj b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.Server/BlazorMultipleApps.Server.csproj
new file mode 100644
index 000000000000..1b71bd775fd5
--- /dev/null
+++ b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.Server/BlazorMultipleApps.Server.csproj
@@ -0,0 +1,14 @@
+
+
+
+ net5.0
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.Server/Program.cs b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.Server/Program.cs
new file mode 100644
index 000000000000..c571651ff9d6
--- /dev/null
+++ b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.Server/Program.cs
@@ -0,0 +1,10 @@
+namespace BlazorMultipleApps.Server
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+
+ }
+ }
+}
diff --git a/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.Shared/BlazorMultipleApps.Shared.csproj b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.Shared/BlazorMultipleApps.Shared.csproj
new file mode 100644
index 000000000000..d4c395e8cb78
--- /dev/null
+++ b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.Shared/BlazorMultipleApps.Shared.csproj
@@ -0,0 +1,7 @@
+
+
+
+ netstandard2.1
+
+
+
diff --git a/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.Shared/WeatherForecast.cs b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.Shared/WeatherForecast.cs
new file mode 100644
index 000000000000..7c92131eaea7
--- /dev/null
+++ b/src/Components/WebAssembly/Sdk/testassets/BlazorMultipleApps.Shared/WeatherForecast.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace BlazorMultipleApps.Shared
+{
+ public class WeatherForecast
+ {
+ public DateTime Date { get; set; }
+
+ public int TemperatureC { get; set; }
+
+ public string Summary { get; set; }
+
+ public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
+ }
+}
diff --git a/src/Components/WebAssembly/Sdk/testassets/RestoreBlazorWasmTestProjects/RestoreBlazorWasmTestProjects.csproj b/src/Components/WebAssembly/Sdk/testassets/RestoreBlazorWasmTestProjects/RestoreBlazorWasmTestProjects.csproj
index 2af6c265d48c..7d1862b9a4e0 100644
--- a/src/Components/WebAssembly/Sdk/testassets/RestoreBlazorWasmTestProjects/RestoreBlazorWasmTestProjects.csproj
+++ b/src/Components/WebAssembly/Sdk/testassets/RestoreBlazorWasmTestProjects/RestoreBlazorWasmTestProjects.csproj
@@ -9,6 +9,7 @@
+