diff --git a/src/Components/WebAssembly/Build/src/ReferenceBlazorBuildFromSource.props b/src/Components/WebAssembly/Build/src/ReferenceBlazorBuildFromSource.props
index 52f45d5fb3..d480df7f95 100644
--- a/src/Components/WebAssembly/Build/src/ReferenceBlazorBuildFromSource.props
+++ b/src/Components/WebAssembly/Build/src/ReferenceBlazorBuildFromSource.props
@@ -10,9 +10,11 @@
$(MSBuildThisFileDirectory)..\..\..\
- <_BlazorJsPath>$(ComponentsRoot)Web.JS\dist\$(Configuration)\blazor.webassembly.js
- <_BlazorJsMapPath>$(ComponentsRoot)Web.JS\dist\$(Configuration)\blazor.webassembly.js.map
- <_BlazorToolsDir>$(MSBuildThisFileDirectory)bin\$(Configuration)\tools\
+ $(Configuration)
+
+ <_BlazorJsPath>$(ComponentsRoot)Web.JS\dist\$(BlazorBuildConfiguration)\blazor.webassembly.js
+ <_BlazorJsMapPath>$(ComponentsRoot)Web.JS\dist\$(BlazorBuildConfiguration)\blazor.webassembly.js.map
+ <_BlazorToolsDir>$(MSBuildThisFileDirectory)bin\$(BlazorBuildConfiguration)\tools\
diff --git a/src/Components/WebAssembly/Build/src/Tasks/GenerateBlazorBootJson.cs b/src/Components/WebAssembly/Build/src/Tasks/GenerateBlazorBootJson.cs
index a99113e0d7..126575ccc0 100644
--- a/src/Components/WebAssembly/Build/src/Tasks/GenerateBlazorBootJson.cs
+++ b/src/Components/WebAssembly/Build/src/Tasks/GenerateBlazorBootJson.cs
@@ -89,7 +89,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
resourceList = resourceData.assembly;
break;
case "pdb":
- resourceData.pdb = new ResourceHashesByNameDictionary();
+ resourceData.pdb ??= new ResourceHashesByNameDictionary();
resourceList = resourceData.pdb;
break;
case "satellite":
diff --git a/src/Components/WebAssembly/Build/src/targets/Blazor.MonoRuntime.targets b/src/Components/WebAssembly/Build/src/targets/Blazor.MonoRuntime.targets
index 36bf22b729..8058d0d8e6 100644
--- a/src/Components/WebAssembly/Build/src/targets/Blazor.MonoRuntime.targets
+++ b/src/Components/WebAssembly/Build/src/targets/Blazor.MonoRuntime.targets
@@ -93,6 +93,7 @@
<_BlazorOutputWithTargetPath Include="@(_BlazorCopyLocalPaths)">
+ pdb
assembly
satellite
%(_BlazorCopyLocalPaths.DestinationSubDirectory)%(FileName)%(Extension)
@@ -108,9 +109,9 @@
<_BlazorOutputWithTargetPath Include="@(_BlazorResolvedAssembly)">
assembly
- pdb
- %(_BlazorCopyLocalPaths.DestinationSubDirectory)%(FileName)%(Extension)
- $(_BlazorRuntimeBinOutputPath)%(_BlazorCopyLocalPaths.DestinationSubDirectory)%(FileName)%(Extension)
+ pdb
+ %(FileName)%(Extension)
+ $(_BlazorRuntimeBinOutputPath)%(FileName)%(Extension)
<_BlazorOutputWithTargetPath Include="@(_DotNetWasmRuntimeFile)">
diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildCompressionTests.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildCompressionTests.cs
index 9e7843813a..d7581bc874 100644
--- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildCompressionTests.cs
+++ b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildCompressionTests.cs
@@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
public async Task Build_WithLinkerAndCompression_IsIncremental()
{
// Arrange
- using var project = ProjectDirectory.Create("standalone");
+ using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" });
var result = await MSBuildProcessManager.DotnetMSBuild(project);
Assert.BuildPassed(result);
@@ -44,7 +44,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
public async Task Build_WithoutLinkerAndCompression_IsIncremental()
{
// Arrange
- using var project = ProjectDirectory.Create("standalone");
+ using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" });
var result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/p:BlazorWebAssemblyEnableLinking=false");
Assert.BuildPassed(result);
@@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
public async Task Build_CompressesAllFrameworkFiles()
{
// Arrange
- using var project = ProjectDirectory.Create("standalone");
+ using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" });
var result = await MSBuildProcessManager.DotnetMSBuild(project);
Assert.BuildPassed(result);
@@ -119,7 +119,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
public async Task Build_DisabledCompression_DoesNotCompressFiles()
{
// Arrange
- using var project = ProjectDirectory.Create("standalone");
+ using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" });
// Act
var result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/p:BlazorEnableCompression=false");
diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildIncrementalismTest.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildIncrementalismTest.cs
index f8c5d1313c..fa132468aa 100644
--- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildIncrementalismTest.cs
+++ b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildIncrementalismTest.cs
@@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
public async Task Build_WithLinker_IsIncremental()
{
// Arrange
- using var project = ProjectDirectory.Create("standalone");
+ using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" });
var result = await MSBuildProcessManager.DotnetMSBuild(project);
Assert.BuildPassed(result);
diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildIntegrationTest.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildIntegrationTest.cs
index bfbb4b2afd..c43b688a56 100644
--- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildIntegrationTest.cs
+++ b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildIntegrationTest.cs
@@ -15,7 +15,8 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
public async Task Build_WithDefaultSettings_Works()
{
// Arrange
- using var project = ProjectDirectory.Create("standalone");
+ using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" });
+ project.Configuration = "Debug";
var result = await MSBuildProcessManager.DotnetMSBuild(project);
Assert.BuildPassed(result);
@@ -27,12 +28,100 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", "dotnet.wasm");
Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", DotNetJsFileName);
Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll");
+ Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "RazorClassLibrary.dll");
Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output.
+ Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.pdb");
+ Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "RazorClassLibrary.pdb");
var staticWebAssets = Assert.FileExists(result, buildOutputDirectory, "standalone.StaticWebAssets.xml");
Assert.FileContains(result, staticWebAssets, Path.Combine("netstandard2.1", "wwwroot"));
}
+ [Fact]
+ public async Task Build_InRelease_Works()
+ {
+ // Arrange
+ using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" });
+ project.Configuration = "Release";
+ var result = await MSBuildProcessManager.DotnetMSBuild(project);
+
+ Assert.BuildPassed(result);
+
+ var buildOutputDirectory = project.BuildOutputDirectory;
+
+ Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json");
+ Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.webassembly.js");
+ Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", "dotnet.wasm");
+ Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", DotNetJsFileName);
+ Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll");
+ Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "RazorClassLibrary.dll");
+ Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output.
+ Assert.FileDoesNotExist(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.pdb");
+ Assert.FileDoesNotExist(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "RazorClassLibrary.pdb");
+
+ var staticWebAssets = Assert.FileExists(result, buildOutputDirectory, "standalone.StaticWebAssets.xml");
+ Assert.FileContains(result, staticWebAssets, Path.Combine("netstandard2.1", "wwwroot"));
+ }
+
+ [Fact]
+ public async Task Build_ProducesBootJsonDataWithExpectedContent()
+ {
+ // Arrange
+ using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" });
+ project.Configuration = "Debug";
+ var result = await MSBuildProcessManager.DotnetMSBuild(project);
+
+ Assert.BuildPassed(result);
+
+ var buildOutputDirectory = project.BuildOutputDirectory;
+
+ var bootJsonPath = Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json");
+ var bootJsonData = ReadBootJsonData(result, bootJsonPath);
+
+ var runtime = bootJsonData.resources.runtime.Keys;
+ Assert.Contains(DotNetJsFileName, runtime);
+ Assert.Contains("dotnet.wasm", runtime);
+
+ var assemblies = bootJsonData.resources.assembly.Keys;
+ Assert.Contains("standalone.dll", assemblies);
+ Assert.Contains("RazorClassLibrary.dll", assemblies);
+ Assert.Contains("Microsoft.Extensions.Logging.Abstractions.dll", assemblies);
+
+ var pdb = bootJsonData.resources.pdb.Keys;
+ Assert.Contains("standalone.pdb", pdb);
+ Assert.Contains("RazorClassLibrary.pdb", pdb);
+
+ Assert.Null(bootJsonData.resources.satelliteResources);
+ }
+
+ [Fact]
+ public async Task Build_InRelease_ProducesBootJsonDataWithExpectedContent()
+ {
+ // Arrange
+ using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" });
+ project.Configuration = "Release";
+ var result = await MSBuildProcessManager.DotnetMSBuild(project);
+
+ Assert.BuildPassed(result);
+
+ var buildOutputDirectory = project.BuildOutputDirectory;
+
+ var bootJsonPath = Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json");
+ var bootJsonData = ReadBootJsonData(result, bootJsonPath);
+
+ var runtime = bootJsonData.resources.runtime.Keys;
+ Assert.Contains(DotNetJsFileName, runtime);
+ Assert.Contains("dotnet.wasm", runtime);
+
+ var assemblies = bootJsonData.resources.assembly.Keys;
+ Assert.Contains("standalone.dll", assemblies);
+ Assert.Contains("RazorClassLibrary.dll", assemblies);
+ Assert.Contains("Microsoft.Extensions.Logging.Abstractions.dll", assemblies);
+
+ Assert.Null(bootJsonData.resources.pdb);
+ Assert.Null(bootJsonData.resources.satelliteResources);
+ }
+
[Fact]
public async Task Build_Hosted_Works()
{
@@ -58,7 +147,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
public async Task Build_WithLinkOnBuildDisabled_Works()
{
// Arrange
- using var project = ProjectDirectory.Create("standalone");
+ using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" });
project.AddProjectFileContent(
@"
false
@@ -91,6 +180,8 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
");
+ var resxfileInProject = Path.Combine(project.DirectoryPath, "Resources.ja.resx.txt");
+ File.Move(resxfileInProject, Path.Combine(project.DirectoryPath, "Resource.ja.resx"));
var result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/restore");
@@ -123,6 +214,9 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
");
+ var resxfileInProject = Path.Combine(project.DirectoryPath, "Resources.ja.resx.txt");
+ File.Move(resxfileInProject, Path.Combine(project.DirectoryPath, "Resource.ja.resx"));
+
var result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/restore");
Assert.BuildPassed(result);
@@ -134,9 +228,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "Microsoft.CodeAnalysis.CSharp.dll");
Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "fr", "Microsoft.CodeAnalysis.CSharp.resources.dll"); // Verify satellite assemblies are present in the build output.
- var bootJson = JsonSerializer.Deserialize(
- File.ReadAllText(Path.Combine(project.DirectoryPath, buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json")),
- new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
+ var bootJson = ReadBootJsonData(result, Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"));
var satelliteResources = bootJson.resources.satelliteResources;
Assert.NotNull(satelliteResources);
@@ -148,5 +240,12 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
Assert.Contains("ja", satelliteResources.Keys);
Assert.Contains("ja/standalone.resources.dll", satelliteResources["ja"].Keys);
}
+
+ private static GenerateBlazorBootJson.BootJsonData ReadBootJsonData(MSBuildResult result, string path)
+ {
+ return JsonSerializer.Deserialize(
+ File.ReadAllText(Path.Combine(result.Project.DirectoryPath, path)),
+ new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
+ }
}
}
diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/MSBuildProcessManager.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/MSBuildProcessManager.cs
index c17c7a32d0..c9e5176399 100644
--- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/MSBuildProcessManager.cs
+++ b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/MSBuildProcessManager.cs
@@ -33,6 +33,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
buildArgumentList.Add($"/t:{target}");
buildArgumentList.Add($"/p:Configuration={project.Configuration}");
+ buildArgumentList.Add($"/p:BlazorBuildConfiguration={ProjectDirectory.TestProjectConfiguration}");
buildArgumentList.Add(args);
var buildArguments = string.Join(" ", buildArgumentList);
diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/ProjectDirectory.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/ProjectDirectory.cs
index 4cb3e96576..2c12d26df0 100644
--- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/ProjectDirectory.cs
+++ b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/ProjectDirectory.cs
@@ -14,6 +14,16 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
{
public bool PreserveWorkingDirectory { get; set; } = false;
+ // Configuration the test project is building in.
+ public static readonly string TestProjectConfiguration
+#if DEBUG
+ = "Debug";
+#elif RELEASE
+ = "Release";
+#else
+#error Configuration not supported
+#endif
+
private static readonly string RepoRoot = GetTestAttribute("Testing.RepoRoot");
public static ProjectDirectory Create(string projectName, string baseDirectory = "", string[] additionalProjects = null)
@@ -142,13 +152,7 @@ $@"
public string TargetFramework { get; set; } = "netstandard2.1";
-#if DEBUG
- public string Configuration => "Debug";
-#elif RELEASE
- public string Configuration => "Release";
-#else
-#error Configuration not supported
-#endif
+ public string Configuration { get; set; } = TestProjectConfiguration;
public string IntermediateOutputDirectory => Path.Combine("obj", Configuration, TargetFramework);
diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/ProjectDirectoryTest.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/ProjectDirectoryTest.cs
index 2fc3499e25..130a14ef8d 100644
--- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/ProjectDirectoryTest.cs
+++ b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/ProjectDirectoryTest.cs
@@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
public void ProjectDirectory_IsNotSetToBePreserved()
{
// Arrange
- using var project = ProjectDirectory.Create("standalone");
+ using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" });
// Act & Assert
// This flag is only meant for local debugging and should not be set when checking in.
diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/PwaManifestTests.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/PwaManifestTests.cs
index 891a0a10c7..a268e8f8ea 100644
--- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/PwaManifestTests.cs
+++ b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/PwaManifestTests.cs
@@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
{
// Arrange
var expectedExtensions = new[] { ".dll", ".pdb", ".js", ".wasm" };
- using var project = ProjectDirectory.Create("standalone");
+ using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" });
var result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/p:ServiceWorkerAssetsManifest=service-worker-assets.js");
Assert.BuildPassed(result);
diff --git a/src/Components/WebAssembly/Build/test/GenerateBlazorBootJsonTest.cs b/src/Components/WebAssembly/Build/test/GenerateBlazorBootJsonTest.cs
index 5520037077..40de7e68a2 100644
--- a/src/Components/WebAssembly/Build/test/GenerateBlazorBootJsonTest.cs
+++ b/src/Components/WebAssembly/Build/test/GenerateBlazorBootJsonTest.cs
@@ -37,6 +37,11 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
name: "otherdir/SomePdb.pdb", // Can specify Linux-style path
fileHash: "pdbhashpdbhashpdbhash"),
+ CreateResourceTaskItem(
+ "pdb",
+ name: "My.Assembly1.pdb",
+ fileHash: "pdbdefghikjlmnopqrstuvwxyz"),
+
CreateResourceTaskItem(
"runtime",
name: "some-runtime-file", // Can specify path with no extension
@@ -77,8 +82,9 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
Assert.Equal("sha256-012345678901234567890123456789", resources["dir/My.Assembly2.ext2"]); // Paths are converted to use URL-style separators
resources = parsedContent.resources.pdb;
- Assert.Single(resources);
+ Assert.Equal(2, resources.Count);
Assert.Equal("sha256-pdbhashpdbhashpdbhash", resources["otherdir/SomePdb.pdb"]);
+ Assert.Equal("sha256-pdbdefghikjlmnopqrstuvwxyz", resources["My.Assembly1.pdb"]);
resources = parsedContent.resources.runtime;
Assert.Single(resources);
diff --git a/src/Components/WebAssembly/Build/testassets/razorclasslibrary/Class1.cs b/src/Components/WebAssembly/Build/testassets/razorclasslibrary/Class1.cs
new file mode 100644
index 0000000000..fb55605ff4
--- /dev/null
+++ b/src/Components/WebAssembly/Build/testassets/razorclasslibrary/Class1.cs
@@ -0,0 +1,6 @@
+namespace RazorClassLibrary
+{
+ public class Class1
+ {
+ }
+}
diff --git a/src/Components/WebAssembly/Build/testassets/standalone/Program.cs b/src/Components/WebAssembly/Build/testassets/standalone/Program.cs
index 3e46e63316..7d2cb4eeea 100644
--- a/src/Components/WebAssembly/Build/testassets/standalone/Program.cs
+++ b/src/Components/WebAssembly/Build/testassets/standalone/Program.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
namespace standalone
{
@@ -6,6 +6,7 @@ namespace standalone
{
public static void Main(string[] args)
{
+ GC.KeepAlive(typeof(RazorClassLibrary.Class1));
#if REFERENCE_classlibrarywithsatelliteassemblies
GC.KeepAlive(typeof(classlibrarywithsatelliteassemblies.Class1));
#endif
diff --git a/src/Components/WebAssembly/Build/testassets/standalone/Resources.ja.resx b/src/Components/WebAssembly/Build/testassets/standalone/Resources.ja.resx.txt
similarity index 93%
rename from src/Components/WebAssembly/Build/testassets/standalone/Resources.ja.resx
rename to src/Components/WebAssembly/Build/testassets/standalone/Resources.ja.resx.txt
index cd5b68cfc5..aabe84e3c0 100644
--- a/src/Components/WebAssembly/Build/testassets/standalone/Resources.ja.resx
+++ b/src/Components/WebAssembly/Build/testassets/standalone/Resources.ja.resx.txt
@@ -1,17 +1,17 @@
-