Add support for <BlazorWebAssemblyLazyLoad /> item group (#23071)

* Add support for <BlazorLazyLoad /> item group
* Respond to feedback from peer review
This commit is contained in:
Safia Abdalla 2020-06-18 16:05:34 -07:00 committed by GitHub
parent ab7f3f2018
commit a173be28fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 186 additions and 1 deletions

View File

@ -88,6 +88,9 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
case "assembly":
resourceList = resourceData.assembly;
break;
case "dynamicAssembly":
resourceList = resourceData.dynamicAssembly;
break;
case "pdb":
resourceData.pdb ??= new ResourceHashesByNameDictionary();
resourceList = resourceData.pdb;
@ -207,6 +210,11 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
/// </summary>
public ResourceHashesByNameDictionary assembly { get; set; } = new ResourceHashesByNameDictionary();
/// <summary>
/// Assembly (.dll) resources that are loaded dynamically during runtime
/// </summary>
public ResourceHashesByNameDictionary dynamicAssembly { get; set; } = new ResourceHashesByNameDictionary();
/// <summary>
/// "debug" (.pdb) resources
/// </summary>
@ -221,4 +229,4 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
}
#pragma warning restore IDE1006 // Naming Styles
}
}
}

View File

@ -129,6 +129,7 @@
<_BlazorOutputWithTargetPath Include="@(_BlazorResolvedAssembly)">
<BootManifestResourceType Condition="'%(Extension)' == '.dll'">assembly</BootManifestResourceType>
<BootManifestResourceType Condition="'%(Extension)' == '.pdb'">pdb</BootManifestResourceType>
<BootManifestResourceType Condition="@(BlazorWebAssemblyLazyLoad->AnyHaveMetadataValue('Identity', '%(Filename)')) != ''">dynamicAssembly</BootManifestResourceType>
<BootManifestResourceName>%(FileName)%(Extension)</BootManifestResourceName>
<TargetOutputPath>$(_BlazorRuntimeBinOutputPath)%(FileName)%(Extension)</TargetOutputPath>
</_BlazorOutputWithTargetPath>

View File

@ -0,0 +1,176 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Testing;
using Xunit;
using static Microsoft.AspNetCore.Components.WebAssembly.Build.WebAssemblyRuntimePackage;
namespace Microsoft.AspNetCore.Components.WebAssembly.Build
{
public class BuildLazyLoadTest
{
[Fact]
public async Task Build_LazyLoadExplicitAssembly_Debug_Works()
{
// Arrange
using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" });
project.Configuration = "Debug";
project.AddProjectFileContent(
@"
<ItemGroup>
<BlazorWebAssemblyLazyLoad Include='RazorClassLibrary.dll' />
</ItemGroup>
");
var result = await MSBuildProcessManager.DotnetMSBuild(project);
var buildOutputDirectory = project.BuildOutputDirectory;
// Verify that a blazor.boot.json file has been created
Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json");
// And that the assembly is in the output
Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "RazorClassLibrary.dll");
var bootJson = ReadBootJsonData(result, Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"));
// And that it has been labelled as a dynamic assembly in the boot.json
var dynamicAssemblies = bootJson.resources.dynamicAssembly;
var assemblies = bootJson.resources.assembly;
Assert.NotNull(dynamicAssemblies);
Assert.Contains("RazorClassLibrary.dll", dynamicAssemblies.Keys);
Assert.DoesNotContain("RazorClassLibrary.dll", assemblies.Keys);
// App assembly should not be lazy loaded
Assert.DoesNotContain("standalone.dll", dynamicAssemblies.Keys);
Assert.Contains("standalone.dll", assemblies.Keys);
}
[Fact]
public async Task Build_LazyLoadExplicitAssembly_Release_Works()
{
// Arrange
using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" });
project.Configuration = "Release";
project.AddProjectFileContent(
@"
<ItemGroup>
<BlazorWebAssemblyLazyLoad Include='RazorClassLibrary.dll' />
</ItemGroup>
");
var result = await MSBuildProcessManager.DotnetMSBuild(project);
var buildOutputDirectory = project.BuildOutputDirectory;
// Verify that a blazor.boot.json file has been created
Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json");
// And that the assembly is in the output
Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "RazorClassLibrary.dll");
var bootJson = ReadBootJsonData(result, Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"));
// And that it has been labelled as a dynamic assembly in the boot.json
var dynamicAssemblies = bootJson.resources.dynamicAssembly;
var assemblies = bootJson.resources.assembly;
Assert.NotNull(dynamicAssemblies);
Assert.Contains("RazorClassLibrary.dll", dynamicAssemblies.Keys);
Assert.DoesNotContain("RazorClassLibrary.dll", assemblies.Keys);
// App assembly should not be lazy loaded
Assert.DoesNotContain("standalone.dll", dynamicAssemblies.Keys);
Assert.Contains("standalone.dll", assemblies.Keys);
}
[Fact]
public async Task Publish_LazyLoadExplicitAssembly_Debug_Works()
{
// Arrange
using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" });
project.Configuration = "Debug";
project.AddProjectFileContent(
@"
<ItemGroup>
<BlazorWebAssemblyLazyLoad Include='RazorClassLibrary.dll' />
</ItemGroup>
");
var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish");
var publishDirectory = project.PublishOutputDirectory;
// Verify that a blazor.boot.json file has been created
Assert.FileExists(result, publishDirectory, "wwwroot", "_framework", "blazor.boot.json");
// And that the assembly is in the output
Assert.FileExists(result, publishDirectory, "wwwroot", "_framework", "_bin", "RazorClassLibrary.dll");
var bootJson = ReadBootJsonData(result, Path.Combine(publishDirectory, "wwwroot", "_framework", "blazor.boot.json"));
// And that it has been labelled as a dynamic assembly in the boot.json
var dynamicAssemblies = bootJson.resources.dynamicAssembly;
var assemblies = bootJson.resources.assembly;
Assert.NotNull(dynamicAssemblies);
Assert.Contains("RazorClassLibrary.dll", dynamicAssemblies.Keys);
Assert.DoesNotContain("RazorClassLibrary.dll", assemblies.Keys);
// App assembly should not be lazy loaded
Assert.DoesNotContain("standalone.dll", dynamicAssemblies.Keys);
Assert.Contains("standalone.dll", assemblies.Keys);
}
[Fact]
public async Task Publish_LazyLoadExplicitAssembly_Release_Works()
{
// Arrange
using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" });
project.Configuration = "Release";
project.AddProjectFileContent(
@"
<ItemGroup>
<BlazorWebAssemblyLazyLoad Include='RazorClassLibrary.dll' />
</ItemGroup>
");
var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish");
var publishDirectory = project.PublishOutputDirectory;
// Verify that a blazor.boot.json file has been created
Assert.FileExists(result, publishDirectory, "wwwroot", "_framework", "blazor.boot.json");
// And that the assembly is in the output
Assert.FileExists(result, publishDirectory, "wwwroot", "_framework", "_bin", "RazorClassLibrary.dll");
var bootJson = ReadBootJsonData(result, Path.Combine(publishDirectory, "wwwroot", "_framework", "blazor.boot.json"));
// And that it has been labelled as a dynamic assembly in the boot.json
var dynamicAssemblies = bootJson.resources.dynamicAssembly;
var assemblies = bootJson.resources.assembly;
Assert.NotNull(dynamicAssemblies);
Assert.Contains("RazorClassLibrary.dll", dynamicAssemblies.Keys);
Assert.DoesNotContain("RazorClassLibrary.dll", assemblies.Keys);
// App assembly should not be lazy loaded
Assert.DoesNotContain("standalone.dll", dynamicAssemblies.Keys);
Assert.Contains("standalone.dll", assemblies.Keys);
}
private static GenerateBlazorBootJson.BootJsonData ReadBootJsonData(MSBuildResult result, string path)
{
return JsonSerializer.Deserialize<GenerateBlazorBootJson.BootJsonData>(
File.ReadAllText(Path.Combine(result.Project.DirectoryPath, path)),
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
}
}
}