Use BlazorWebAssemblySDK (#24371)
* Use BlazorWebAssemblySDK * Update projects to use the BlazorSDK * Remove tasks and targets from RazorSDK * Remove workarounds from BlazorSDK * Fixup * Fixup
This commit is contained in:
parent
7efec87a14
commit
8e5533f2a3
|
|
@ -12,7 +12,7 @@
|
|||
<PackageReference Include="MicroBuild.Core" Version="0.3.0" PrivateAssets="All" AllowExplicitReference="true" ExcludeAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(UsingMicrosoftNETSdkWeb)' == 'true' OR '$(RazorSdkCurrentVersionProps)' != ''">
|
||||
<ItemGroup Condition="'$(UsingMicrosoftNETSdkWeb)' == 'true' OR '$(UsingMicrosoftNETSdkBlazorWebAssembly)' == 'true' OR '$(RazorSdkCurrentVersionProps)' != ''">
|
||||
<!--
|
||||
Use the Razor SDK as a project reference. The version of the .NET Core SDK we build with often contains a version of the Razor SDK
|
||||
several versions older than latest. We reference the project to ensure it's built before the other projects that use it. Since this
|
||||
|
|
@ -25,11 +25,28 @@
|
|||
UndefineProperties="TargetFramework;TargetFrameworks" />
|
||||
</ItemGroup>
|
||||
|
||||
<ImportGroup Condition="'$(UsingMicrosoftNETSdkWeb)' == 'true' OR '$(RazorSdkCurrentVersionProps)' != ''">
|
||||
<ImportGroup Condition="'$(UsingMicrosoftNETSdkWeb)' == 'true' OR '$(UsingMicrosoftNETSdkBlazorWebAssembly)' == 'true' OR '$(RazorSdkCurrentVersionProps)' != ''">
|
||||
<Import Project="$(RepoRoot)eng\targets\GetRazorSDKDirectory.props" />
|
||||
<Import Project="$(RepoRoot)src\Razor\Microsoft.NET.Sdk.Razor\src\build\netstandard2.0\Microsoft.NET.Sdk.Razor.props" />
|
||||
</ImportGroup>
|
||||
|
||||
<ItemGroup Condition="'$(UsingMicrosoftNETSdkBlazorWebAssembly)' == 'true'">
|
||||
<!-- See comments further up in the file when we import the Razor SDK-->
|
||||
<Reference Include="Microsoft.NET.Sdk.BlazorWebAssembly"
|
||||
PrivateAssets="All"
|
||||
ReferenceOutputAssembly="false"
|
||||
SkipGetTargetFrameworkProperties="true"
|
||||
UndefineProperties="TargetFramework;TargetFrameworks" />
|
||||
</ItemGroup>
|
||||
|
||||
<ImportGroup Condition="'$(UsingMicrosoftNETSdkBlazorWebAssembly)' == 'true'">
|
||||
<Import Project="$(RepoRoot)src\Components\WebAssembly\Sdk\src\build\net5.0\Microsoft.NET.Sdk.BlazorWebAssembly.props" />
|
||||
</ImportGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(UsingMicrosoftNETSdkBlazorWebAssembly)' == 'true'">
|
||||
<BlazorWebAssemblySdkDirectoryRoot>$(ArtifactsBinDir)\Microsoft.NET.Sdk.BlazorWebAssembly\$(Configuration)\sdk-output\</BlazorWebAssemblySdkDirectoryRoot>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(IsTestProject)' != 'true' AND '$(DotNetBuildFromSource)' != 'true' ">
|
||||
<Reference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<Project>
|
||||
<PropertyGroup Condition="'$(UseBlazorWebAssembly)' == 'true'">
|
||||
<PropertyGroup Condition="'$(UsingMicrosoftNETSdkBlazorWebAssembly)' == 'true'">
|
||||
<BlazorWebAssemblyJSPath>$(RepoRoot)src\Components\Web.JS\dist\$(Configuration)\blazor.webassembly.js</BlazorWebAssemblyJSPath>
|
||||
<BlazorWebAssemblyJSMapPath>$(BlazorWebAssemblyJSPath).map</BlazorWebAssemblyJSMapPath>
|
||||
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
<!-- Add a project dependency without reference output assemblies to enforce build order -->
|
||||
<!-- Applying workaround for https://github.com/microsoft/msbuild/issues/2661 and https://github.com/dotnet/sdk/issues/952 -->
|
||||
<ProjectReference
|
||||
Condition="'$(UseBlazorWebAssembly)' == 'true' and '$(BuildNodeJS)' != 'false' and '$(BuildingInsideVisualStudio)' != 'true'"
|
||||
Condition="'$(UsingMicrosoftNETSdkBlazorWebAssembly)' == 'true' and '$(BuildNodeJS)' != 'false' and '$(BuildingInsideVisualStudio)' != 'true'"
|
||||
Include="$(RepoRoot)src\Components\Web.JS\Microsoft.AspNetCore.Components.Web.JS.npmproj"
|
||||
ReferenceOutputAssemblies="false"
|
||||
SkipGetTargetFrameworkProperties="true"
|
||||
|
|
|
|||
|
|
@ -321,6 +321,8 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
project.AddProjectFileContent(
|
||||
@"
|
||||
<PropertyGroup>
|
||||
<!-- Workaround for https://github.com/mono/linker/issues/1390 -->
|
||||
<PublishTrimmed>false</PublishTrimmed>
|
||||
<DefineConstants>$(DefineConstants);REFERENCE_classlibrarywithsatelliteassemblies</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
|
|
@ -450,6 +452,8 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
wasmProject.AddProjectFileContent(
|
||||
@"
|
||||
<PropertyGroup>
|
||||
<!-- Workaround for https://github.com/mono/linker/issues/1390 -->
|
||||
<PublishTrimmed>false</PublishTrimmed>
|
||||
<DefineConstants>$(DefineConstants);REFERENCE_classlibrarywithsatelliteassemblies</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
|
|
@ -637,7 +641,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
// Arrange
|
||||
using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "blazorwasm", "razorclasslibrary", });
|
||||
File.WriteAllText(Path.Combine(project.SolutionPath, "blazorwasm", "App.razor.css"), "h1 { font-size: 16px; }");
|
||||
|
||||
|
||||
project.Configuration = "Release";
|
||||
var result = await MSBuildProcessManager.DotnetMSBuild(project, "Build", "/p:BuildInsideVisualStudio=true");
|
||||
|
||||
|
|
@ -701,6 +705,8 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
var existing = File.ReadAllText(blazorwasmProjFile);
|
||||
var updatedContent = @"
|
||||
<PropertyGroup>
|
||||
<!-- Workaround for https://github.com/mono/linker/issues/1390 -->
|
||||
<PublishTrimmed>false</PublishTrimmed>
|
||||
<DefineConstants>$(DefineConstants);REFERENCE_classlibrarywithsatelliteassemblies</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -12,5 +12,6 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
<Project ToolsVersion="14.0">
|
||||
<PropertyGroup>
|
||||
<_BlazorWebAssemblyPropsFile>$(MSBuildThisFileDirectory)..\..\targets\Microsoft.NET.Sdk.BlazorWebAssembly.Current.props</_BlazorWebAssemblyPropsFile>
|
||||
<_BlazorWebAssemblyTargetsFile>$(MSBuildThisFileDirectory)..\..\targets\Microsoft.NET.Sdk.BlazorWebAssembly.Current.targets</_BlazorWebAssemblyTargetsFile>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
<!--
|
||||
***********************************************************************************************
|
||||
Microsoft.NET.Sdk.BlazorWebAssembly.props
|
||||
|
||||
WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
|
||||
created a backup copy. Incorrect changes to this file will make it
|
||||
impossible to load or build your projects from the command-line or the IDE.
|
||||
|
||||
Copyright (c) .NET Foundation. All rights reserved.
|
||||
***********************************************************************************************
|
||||
-->
|
||||
<Project ToolsVersion="14.0">
|
||||
<PropertyGroup>
|
||||
<_BlazorWebAssemblyTargetsFile>$(MSBuildThisFileDirectory)..\..\targets\Microsoft.NET.Sdk.BlazorWebAssembly.Current.targets</_BlazorWebAssemblyTargetsFile>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -24,12 +24,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
<WarnOnPackingNonPackableProject>false</WarnOnPackingNonPackableProject>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Determines if this Sdk is responsible for importing Microsoft.NET.Sdk.Razor. Temporary workaround until we can create a SDK. -->
|
||||
<_RazorSdkImportsMicrosoftNetSdkRazor Condition="'$(UsingMicrosoftNETSdkRazor)' != 'true'">true</_RazorSdkImportsMicrosoftNetSdkRazor>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Sdk="Microsoft.NET.Sdk.Razor" Project="Sdk.props" Condition="'$(_RazorSdkImportsMicrosoftNetSdkRazor)' == 'true'" />
|
||||
<Import Sdk="Microsoft.NET.Sdk.Razor" Project="Sdk.props" />
|
||||
<Import Sdk="Microsoft.NET.Sdk.Web.ProjectSystem" Project="Sdk.props" />
|
||||
<Import Sdk="Microsoft.NET.Sdk.Publish" Project="Sdk.props" />
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
<EnableDefaultContentItems Condition=" '$(EnableDefaultContentItems)' == '' ">true</EnableDefaultContentItems>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Sdk="Microsoft.NET.Sdk.Razor" Project="Sdk.targets" Condition="'$(_RazorSdkImportsMicrosoftNetSdkRazor)' == 'true'" />
|
||||
<Import Sdk="Microsoft.NET.Sdk.Razor" Project="Sdk.targets" />
|
||||
<Import Sdk="Microsoft.NET.Sdk.Web.ProjectSystem" Project="Sdk.targets" />
|
||||
<Import Sdk="Microsoft.NET.Sdk.Publish" Project="Sdk.targets" />
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
|
||||
<Import Project="$(RepoRoot)src\Components\WebAssembly\Sdk\src\Sdk\Sdk.props" />
|
||||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
|
|
@ -26,6 +24,4 @@
|
|||
<Reference Include="$(BinariesRoot)\Microsoft.AspNetCore.Razor.Test.ComponentShim.dll"/>
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="$(RepoRoot)src\Components\WebAssembly\Sdk\src\Sdk\Sdk.targets" />
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
|
||||
<Import Project="$(RepoRoot)src\Components\WebAssembly\Sdk\src\Sdk\Sdk.props" />
|
||||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
|
|
@ -52,6 +50,4 @@
|
|||
<ServiceWorker Include="wwwroot\serviceworkers\my-service-worker.js" PublishedContent="wwwroot\serviceworkers\my-prod-service-worker.js" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="$(RepoRoot)src\Components\WebAssembly\Sdk\src\Sdk\Sdk.targets" />
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
|
||||
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
|
||||
<UseBlazorWebAssembly>true</UseBlazorWebAssembly>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
|
||||
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
|
||||
<UseBlazorWebAssembly>true</UseBlazorWebAssembly>
|
||||
<FixupWebAssemblyHttpHandlerReference>true</FixupWebAssemblyHttpHandlerReference>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
|
||||
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
|
||||
<UseBlazorWebAssembly>true</UseBlazorWebAssembly>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
|
||||
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
|
||||
<UseBlazorWebAssembly>true</UseBlazorWebAssembly>
|
||||
<IsTestAssetProject>true</IsTestAssetProject>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
|
||||
<UseBlazorWebAssembly>true</UseBlazorWebAssembly>
|
||||
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
|
||||
|
||||
<!-- Must be defined before ReferenceFromSource.props is imported -->
|
||||
<AdditionalRunArguments>--pathbase /subdir</AdditionalRunArguments>
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@
|
|||
|
||||
<GenerateFileFromTemplate
|
||||
TemplateFile="$(MSBuildThisFileDirectory)Infrastructure\Directory.Build.props.in"
|
||||
Properties=""
|
||||
Properties="RepoRoot=$(RepoRoot)"
|
||||
OutputPath="$(TestTemplateCreationFolder)Directory.Build.props" />
|
||||
|
||||
<!-- Workaround https://github.com/dotnet/core-setup/issues/6420 - there is no MSBuild setting for rollforward yet -->
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ namespace Templates.Test
|
|||
Environment.SetEnvironmentVariable("EnableDefaultScopedCssItems", "true");
|
||||
|
||||
var project = await ProjectFactory.GetOrCreateProject("blazorstandalone", Output);
|
||||
project.RuntimeIdentifier = "browser-wasm";
|
||||
|
||||
var createResult = await project.RunDotNetNewAsync("blazorwasm");
|
||||
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", project, createResult));
|
||||
|
|
@ -145,7 +144,6 @@ namespace Templates.Test
|
|||
Environment.SetEnvironmentVariable("EnableDefaultScopedCssItems", "true");
|
||||
|
||||
var project = await ProjectFactory.GetOrCreateProject("blazorstandalonepwa", Output);
|
||||
project.RuntimeIdentifier = "browser-wasm";
|
||||
|
||||
var createResult = await project.RunDotNetNewAsync("blazorwasm", args: new[] { "--pwa" });
|
||||
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", project, createResult));
|
||||
|
|
@ -355,7 +353,6 @@ namespace Templates.Test
|
|||
Environment.SetEnvironmentVariable("EnableDefaultScopedCssItems", "true");
|
||||
|
||||
var project = await ProjectFactory.GetOrCreateProject("blazorstandaloneindividual", Output);
|
||||
project.RuntimeIdentifier = "browser-wasm";
|
||||
|
||||
var createResult = await project.RunDotNetNewAsync("blazorwasm", args: new[] {
|
||||
"-au",
|
||||
|
|
|
|||
|
|
@ -3,4 +3,6 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<Import Project="${RepoRoot}src\Components\WebAssembly\Sdk\src\build\net5.0\Microsoft.NET.Sdk.BlazorWebAssembly.props" Condition="'$(UsingMicrosoftNETSdkBlazorWebAssembly)' == 'true'" />
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
-->
|
||||
<PropertyGroup>
|
||||
<RazorSdkDirectoryRoot>${ArtifactsBinDir}Microsoft.NET.Sdk.Razor\${Configuration}\sdk-output\</RazorSdkDirectoryRoot>
|
||||
<BlazorWebAssemblySdkDirectoryRoot>${ArtifactsBinDir}Microsoft.NET.Sdk.BlazorWebAssembly\${Configuration}\sdk-output\</BlazorWebAssemblySdkDirectoryRoot>
|
||||
</PropertyGroup>
|
||||
<Import Project="${RepoRoot}src\Razor\Microsoft.NET.Sdk.Razor\src\build\netstandard2.0\Microsoft.NET.Sdk.Razor.props" Condition="'$(UsingMicrosoftNETSdkWeb)' == 'true' OR '$(RazorSdkCurrentVersionProps)' != ''" />
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>${DefaultNetCoreTargetFramework}</TargetFramework>
|
||||
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
|
||||
<UseBlazorWebAssembly>true</UseBlazorWebAssembly>
|
||||
<!--#if PWA -->
|
||||
<ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest>
|
||||
<!--#endif -->
|
||||
|
|
|
|||
|
|
@ -37,4 +37,5 @@
|
|||
<RazorSdkDirectoryRoot>${ArtifactsBinDir}Microsoft.NET.Sdk.Razor\${Configuration}\sdk-output\</RazorSdkDirectoryRoot>
|
||||
</PropertyGroup>
|
||||
<Import Project="${RepoRoot}src\Razor\Microsoft.NET.Sdk.Razor\src\build\netstandard2.0\Microsoft.NET.Sdk.Razor.props" Condition="'$(UsingMicrosoftNETSdkWeb)' == 'true' OR '$(RazorSdkCurrentVersionProps)' != ''" />
|
||||
<Import Project="${RepoRoot}src\Components\WebAssembly\Sdk\src\build\net5.0\Microsoft.NET.Sdk.BlazorWebAssembly.props" Condition="'$(UsingMicrosoftNETSdkBlazorWebAssembly)' == 'true'" />
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@
|
|||
|
||||
<GenerateFileFromTemplate
|
||||
TemplateFile="$(MSBuildThisFileDirectory)Infrastructure\Directory.Build.props.in"
|
||||
Properties=""
|
||||
Properties="RepoRoot=$(RepoRoot)"
|
||||
OutputPath="$(TestTemplateCreationFolder)Directory.Build.props" />
|
||||
|
||||
<!-- Workaround https://github.com/dotnet/core-setup/issues/6420 - there is no MSBuild setting for rollforward yet -->
|
||||
|
|
|
|||
|
|
@ -33,11 +33,6 @@
|
|||
<Reference Include="Microsoft.NET.Sdk.Razor" ReferenceOutputAssembly="false" SkipGetTargetFrameworkProperties="true" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\src\BootJsonData.cs" LinkBase="Wasm" />
|
||||
<Compile Include="..\src\AssetsManifestFile.cs" LinkBase="Wasm" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="GenerateTestData" BeforeTargets="GetAssemblyAttributes">
|
||||
<Exec Condition="'$(OS)' == 'Windows_NT'" Command=""$(NuGetPackageRoot)vswhere\$(VSWhereVersion)\tools\vswhere.exe" -latest -prerelease -property installationPath -requires Microsoft.Component.MSBuild" ConsoleToMsBuild="true" StandardErrorImportance="high">
|
||||
<Output TaskParameter="ConsoleOutput" PropertyName="_VSInstallDir" />
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Tasks
|
||||
{
|
||||
#pragma warning disable IDE1006 // Naming Styles
|
||||
public class AssetsManifestFile
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a version string.
|
||||
/// </summary>
|
||||
public string version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the assets. Keys are URLs; values are base-64-formatted SHA256 content hashes.
|
||||
/// </summary>
|
||||
public AssetsManifestFileEntry[] assets { get; set; }
|
||||
}
|
||||
|
||||
public class AssetsManifestFileEntry
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the asset URL. Normally this will be relative to the application's base href.
|
||||
/// </summary>
|
||||
public string url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the file content hash. This should be the base-64-formatted SHA256 value.
|
||||
/// </summary>
|
||||
public string hash { get; set; }
|
||||
}
|
||||
#pragma warning restore IDE1006 // Naming Styles
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
// 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.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Tasks
|
||||
{
|
||||
public class BlazorReadSatelliteAssemblyFile : Task
|
||||
{
|
||||
[Output]
|
||||
public ITaskItem[] SatelliteAssembly { get; set; }
|
||||
|
||||
[Required]
|
||||
public ITaskItem ReadFile { get; set; }
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
var document = XDocument.Load(ReadFile.ItemSpec);
|
||||
SatelliteAssembly = document.Root
|
||||
.Elements()
|
||||
.Select(e =>
|
||||
{
|
||||
// <Assembly Name="..." Culture="..." DestinationSubDirectory="..." />
|
||||
|
||||
var taskItem = new TaskItem(e.Attribute("Name").Value);
|
||||
taskItem.SetMetadata("Culture", e.Attribute("Culture").Value);
|
||||
taskItem.SetMetadata("DestinationSubDirectory", e.Attribute("DestinationSubDirectory").Value);
|
||||
|
||||
return taskItem;
|
||||
}).ToArray();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
// 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.IO;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Tasks
|
||||
{
|
||||
public class BlazorWriteSatelliteAssemblyFile : Task
|
||||
{
|
||||
[Required]
|
||||
public ITaskItem[] SatelliteAssembly { get; set; }
|
||||
|
||||
[Required]
|
||||
public ITaskItem WriteFile { get; set; }
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
using var fileStream = File.Create(WriteFile.ItemSpec);
|
||||
WriteSatelliteAssemblyFile(fileStream);
|
||||
return true;
|
||||
}
|
||||
|
||||
internal void WriteSatelliteAssemblyFile(Stream stream)
|
||||
{
|
||||
var root = new XElement("SatelliteAssembly");
|
||||
|
||||
foreach (var item in SatelliteAssembly)
|
||||
{
|
||||
// <Assembly Name="..." Culture="..." DestinationSubDirectory="..." />
|
||||
|
||||
root.Add(new XElement("Assembly",
|
||||
new XAttribute("Name", item.ItemSpec),
|
||||
new XAttribute("Culture", item.GetMetadata("Culture")),
|
||||
new XAttribute("DestinationSubDirectory", item.GetMetadata("DestinationSubDirectory"))));
|
||||
}
|
||||
|
||||
var xmlWriterSettings = new XmlWriterSettings
|
||||
{
|
||||
Indent = true,
|
||||
OmitXmlDeclaration = true
|
||||
};
|
||||
|
||||
using var writer = XmlWriter.Create(stream, xmlWriterSettings);
|
||||
var xDocument = new XDocument(root);
|
||||
|
||||
xDocument.Save(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
// 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.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using ResourceHashesByNameDictionary = System.Collections.Generic.Dictionary<string, string>;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Tasks
|
||||
{
|
||||
#pragma warning disable IDE1006 // Naming Styles
|
||||
/// <summary>
|
||||
/// Defines the structure of a Blazor boot JSON file
|
||||
/// </summary>
|
||||
public class BootJsonData
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name of the assembly with the application entry point
|
||||
/// </summary>
|
||||
public string entryAssembly { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the set of resources needed to boot the application. This includes the transitive
|
||||
/// closure of .NET assemblies (including the entrypoint assembly), the dotnet.wasm file,
|
||||
/// and any PDBs to be loaded.
|
||||
///
|
||||
/// Within <see cref="ResourceHashesByNameDictionary"/>, dictionary keys are resource names,
|
||||
/// and values are SHA-256 hashes formatted in prefixed base-64 style (e.g., 'sha256-abcdefg...')
|
||||
/// as used for subresource integrity checking.
|
||||
/// </summary>
|
||||
public ResourcesData resources { get; set; } = new ResourcesData();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that determines whether to enable caching of the <see cref="resources"/>
|
||||
/// inside a CacheStorage instance within the browser.
|
||||
/// </summary>
|
||||
public bool cacheBootResources { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that determines if this is a debug build.
|
||||
/// </summary>
|
||||
public bool debugBuild { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that determines if the linker is enabled.
|
||||
/// </summary>
|
||||
public bool linkerEnabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Config files for the application
|
||||
/// </summary>
|
||||
public List<string> config { get; set; }
|
||||
}
|
||||
|
||||
public class ResourcesData
|
||||
{
|
||||
/// <summary>
|
||||
/// .NET Wasm runtime resources (dotnet.wasm, dotnet.js) etc.
|
||||
/// </summary>
|
||||
public ResourceHashesByNameDictionary runtime { get; set; } = new ResourceHashesByNameDictionary();
|
||||
|
||||
/// <summary>
|
||||
/// "assembly" (.dll) resources
|
||||
/// </summary>
|
||||
public ResourceHashesByNameDictionary assembly { get; set; } = new ResourceHashesByNameDictionary();
|
||||
|
||||
/// <summary>
|
||||
/// "debug" (.pdb) resources
|
||||
/// </summary>
|
||||
[DataMember(EmitDefaultValue = false)]
|
||||
public ResourceHashesByNameDictionary pdb { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// localization (.satellite resx) resources
|
||||
/// </summary>
|
||||
[DataMember(EmitDefaultValue = false)]
|
||||
public Dictionary<string, ResourceHashesByNameDictionary> satelliteResources { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Assembly (.dll) resources that are loaded lazily during runtime
|
||||
/// </summary>
|
||||
[DataMember(EmitDefaultValue = false)]
|
||||
public ResourceHashesByNameDictionary lazyAssembly { get; set; }
|
||||
}
|
||||
#pragma warning restore IDE1006 // Naming Styles
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
// 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.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Tasks
|
||||
{
|
||||
public class BrotliCompress : DotNetToolTask
|
||||
{
|
||||
private static readonly char[] InvalidPathChars = Path.GetInvalidFileNameChars();
|
||||
|
||||
[Required]
|
||||
public ITaskItem[] FilesToCompress { get; set; }
|
||||
|
||||
[Output]
|
||||
public ITaskItem[] CompressedFiles { get; set; }
|
||||
|
||||
[Required]
|
||||
public string OutputDirectory { get; set; }
|
||||
|
||||
public string CompressionLevel { get; set; }
|
||||
|
||||
public bool SkipIfOutputIsNewer { get; set; }
|
||||
|
||||
internal override string Command => "brotli";
|
||||
|
||||
protected override string GenerateResponseFileCommands()
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
|
||||
builder.AppendLine(Command);
|
||||
|
||||
if (!string.IsNullOrEmpty(CompressionLevel))
|
||||
{
|
||||
builder.AppendLine("-c");
|
||||
builder.AppendLine(CompressionLevel);
|
||||
}
|
||||
|
||||
CompressedFiles = new ITaskItem[FilesToCompress.Length];
|
||||
|
||||
for (var i = 0; i < FilesToCompress.Length; i++)
|
||||
{
|
||||
var input = FilesToCompress[i];
|
||||
var inputFullPath = input.GetMetadata("FullPath");
|
||||
var relativePath = input.GetMetadata("RelativePath");
|
||||
var outputRelativePath = Path.Combine(OutputDirectory, CalculateTargetPath(relativePath, ".br"));
|
||||
|
||||
var outputItem = new TaskItem(outputRelativePath);
|
||||
input.CopyMetadataTo(outputItem);
|
||||
// Relative path in the publish dir
|
||||
outputItem.SetMetadata("RelativePath", relativePath + ".br");
|
||||
CompressedFiles[i] = outputItem;
|
||||
|
||||
var outputFullPath = Path.GetFullPath(outputRelativePath);
|
||||
|
||||
if (SkipIfOutputIsNewer && File.Exists(outputFullPath) && File.GetLastWriteTimeUtc(inputFullPath) < File.GetLastWriteTimeUtc(outputFullPath))
|
||||
{
|
||||
Log.LogMessage(MessageImportance.Low, $"Skipping compression for '{input.ItemSpec}' because '{outputRelativePath}' is newer than '{input.ItemSpec}'.");
|
||||
continue;
|
||||
}
|
||||
|
||||
builder.AppendLine("-s");
|
||||
builder.AppendLine(inputFullPath);
|
||||
|
||||
builder.AppendLine("-o");
|
||||
builder.AppendLine(outputFullPath);
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
internal static string CalculateTargetPath(string relativePath, string extension)
|
||||
{
|
||||
// RelativePath can be long and if used as-is to write the output, might result in long path issues on Windows.
|
||||
// Instead we'll calculate a fixed length path by hashing the input file name. This uses SHA1 similar to the Hash task in MSBuild
|
||||
// since it has no crytographic significance.
|
||||
using var hash = SHA1.Create();
|
||||
var bytes = Encoding.UTF8.GetBytes(relativePath);
|
||||
var hashString = Convert.ToBase64String(hash.ComputeHash(bytes));
|
||||
|
||||
var builder = new StringBuilder();
|
||||
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
var c = hashString[i];
|
||||
builder.Append(InvalidPathChars.Contains(c) ? '+' : c);
|
||||
}
|
||||
|
||||
builder.Append(extension);
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
// 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.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Tasks
|
||||
{
|
||||
// Based on https://github.com/mono/linker/blob/3b329b9481e300bcf4fb88a2eebf8cb5ef8b323b/src/ILLink.Tasks/CreateRootDescriptorFile.cs
|
||||
public class CreateBlazorTrimmerRootDescriptorFile : Task
|
||||
{
|
||||
[Required]
|
||||
public ITaskItem[] Assemblies { get; set; }
|
||||
|
||||
[Required]
|
||||
public ITaskItem TrimmerFile { get; set; }
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
var rootDescriptor = CreateRootDescriptorContents();
|
||||
if (File.Exists(TrimmerFile.ItemSpec))
|
||||
{
|
||||
var existing = File.ReadAllText(TrimmerFile.ItemSpec);
|
||||
|
||||
if (string.Equals(rootDescriptor, existing, StringComparison.Ordinal))
|
||||
{
|
||||
Log.LogMessage(MessageImportance.Low, "Skipping write to file {0} because contents would not change.", TrimmerFile.ItemSpec);
|
||||
// Avoid writing if the file contents are identical. This is required for build incrementalism.
|
||||
return !Log.HasLoggedErrors;
|
||||
}
|
||||
}
|
||||
|
||||
File.WriteAllText(TrimmerFile.ItemSpec, rootDescriptor);
|
||||
return !Log.HasLoggedErrors;
|
||||
}
|
||||
|
||||
internal string CreateRootDescriptorContents()
|
||||
{
|
||||
var roots = new XElement("linker");
|
||||
foreach (var assembly in Assemblies.OrderBy(a => a.ItemSpec))
|
||||
{
|
||||
// NOTE: Descriptor files don't include the file extension
|
||||
// in the assemblyName.
|
||||
var assemblyName = assembly.GetMetadata("FileName");
|
||||
var typePreserved = assembly.GetMetadata("Preserve");
|
||||
var typeRequired = assembly.GetMetadata("Required");
|
||||
|
||||
var attributes = new List<XAttribute>
|
||||
{
|
||||
new XAttribute("fullname", "*"),
|
||||
new XAttribute("required", typeRequired),
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(typePreserved))
|
||||
{
|
||||
attributes.Add(new XAttribute("preserve", typePreserved));
|
||||
}
|
||||
|
||||
roots.Add(new XElement("assembly",
|
||||
new XAttribute("fullname", assemblyName),
|
||||
new XElement("type", attributes)));
|
||||
}
|
||||
|
||||
var xmlWriterSettings = new XmlWriterSettings
|
||||
{
|
||||
Indent = true,
|
||||
OmitXmlDeclaration = true
|
||||
};
|
||||
|
||||
return new XDocument(roots).Root.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
// 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.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Tasks
|
||||
{
|
||||
public class GZipCompress : Task
|
||||
{
|
||||
[Required]
|
||||
public ITaskItem[] FilesToCompress { get; set; }
|
||||
|
||||
[Output]
|
||||
public ITaskItem[] CompressedFiles { get; set; }
|
||||
|
||||
[Required]
|
||||
public string OutputDirectory { get; set; }
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
CompressedFiles = new ITaskItem[FilesToCompress.Length];
|
||||
|
||||
Directory.CreateDirectory(OutputDirectory);
|
||||
|
||||
System.Threading.Tasks.Parallel.For(0, FilesToCompress.Length, i =>
|
||||
{
|
||||
var file = FilesToCompress[i];
|
||||
var inputPath = file.ItemSpec;
|
||||
var relativePath = file.GetMetadata("RelativePath");
|
||||
var outputRelativePath = Path.Combine(
|
||||
OutputDirectory,
|
||||
BrotliCompress.CalculateTargetPath(relativePath, ".gz"));
|
||||
|
||||
var outputItem = new TaskItem(outputRelativePath);
|
||||
outputItem.SetMetadata("RelativePath", relativePath + ".gz");
|
||||
CompressedFiles[i] = outputItem;
|
||||
|
||||
if (File.Exists(outputRelativePath) && File.GetLastWriteTimeUtc(inputPath) < File.GetLastWriteTimeUtc(outputRelativePath))
|
||||
{
|
||||
// Incrementalism. If input source doesn't exist or it exists and is not newer than the expected output, do nothing.
|
||||
Log.LogMessage(MessageImportance.Low, $"Skipping '{inputPath}' because '{outputRelativePath}' is newer than '{inputPath}'.");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using var sourceStream = File.OpenRead(inputPath);
|
||||
using var fileStream = File.Create(outputRelativePath);
|
||||
using var stream = new GZipStream(fileStream, CompressionLevel.Optimal);
|
||||
|
||||
sourceStream.CopyTo(stream);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.LogErrorFromException(e);
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
return !Log.HasLoggedErrors;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,155 +0,0 @@
|
|||
// 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.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization.Json;
|
||||
using System.Text;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
using ResourceHashesByNameDictionary = System.Collections.Generic.Dictionary<string, string>;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Tasks
|
||||
{
|
||||
public class GenerateBlazorWebAssemblyBootJson : Task
|
||||
{
|
||||
[Required]
|
||||
public string AssemblyPath { get; set; }
|
||||
|
||||
[Required]
|
||||
public ITaskItem[] Resources { get; set; }
|
||||
|
||||
[Required]
|
||||
public bool DebugBuild { get; set; }
|
||||
|
||||
[Required]
|
||||
public bool LinkerEnabled { get; set; }
|
||||
|
||||
[Required]
|
||||
public bool CacheBootResources { get; set; }
|
||||
|
||||
public ITaskItem[] ConfigurationFiles { get; set; }
|
||||
|
||||
[Required]
|
||||
public string OutputPath { get; set; }
|
||||
|
||||
public ITaskItem[] LazyLoadedAssemblies { get; set; }
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
using var fileStream = File.Create(OutputPath);
|
||||
var entryAssemblyName = AssemblyName.GetAssemblyName(AssemblyPath).Name;
|
||||
|
||||
try
|
||||
{
|
||||
WriteBootJson(fileStream, entryAssemblyName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.LogErrorFromException(ex);
|
||||
}
|
||||
|
||||
return !Log.HasLoggedErrors;
|
||||
}
|
||||
|
||||
// Internal for tests
|
||||
public void WriteBootJson(Stream output, string entryAssemblyName)
|
||||
{
|
||||
var result = new BootJsonData
|
||||
{
|
||||
entryAssembly = entryAssemblyName,
|
||||
cacheBootResources = CacheBootResources,
|
||||
debugBuild = DebugBuild,
|
||||
linkerEnabled = LinkerEnabled,
|
||||
resources = new ResourcesData(),
|
||||
config = new List<string>(),
|
||||
};
|
||||
|
||||
// Build a two-level dictionary of the form:
|
||||
// - assembly:
|
||||
// - UriPath (e.g., "System.Text.Json.dll")
|
||||
// - ContentHash (e.g., "4548fa2e9cf52986")
|
||||
// - runtime:
|
||||
// - UriPath (e.g., "dotnet.js")
|
||||
// - ContentHash (e.g., "3448f339acf512448")
|
||||
if (Resources != null)
|
||||
{
|
||||
var resourceData = result.resources;
|
||||
foreach (var resource in Resources)
|
||||
{
|
||||
ResourceHashesByNameDictionary resourceList;
|
||||
|
||||
var fileName = resource.GetMetadata("FileName");
|
||||
var extension = resource.GetMetadata("Extension");
|
||||
var resourceCulture = resource.GetMetadata("Culture");
|
||||
var assetType = resource.GetMetadata("AssetType");
|
||||
var resourceName = $"{fileName}{extension}";
|
||||
|
||||
if (IsLazyLoadedAssembly(fileName))
|
||||
{
|
||||
resourceData.lazyAssembly ??= new ResourceHashesByNameDictionary();
|
||||
resourceList = resourceData.lazyAssembly;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(resourceCulture))
|
||||
{
|
||||
resourceData.satelliteResources ??= new Dictionary<string, ResourceHashesByNameDictionary>(StringComparer.OrdinalIgnoreCase);
|
||||
resourceName = resourceCulture + "/" + resourceName;
|
||||
|
||||
if (!resourceData.satelliteResources.TryGetValue(resourceCulture, out resourceList))
|
||||
{
|
||||
resourceList = new ResourceHashesByNameDictionary();
|
||||
resourceData.satelliteResources.Add(resourceCulture, resourceList);
|
||||
}
|
||||
}
|
||||
else if (string.Equals(extension, ".pdb", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
resourceData.pdb ??= new ResourceHashesByNameDictionary();
|
||||
resourceList = resourceData.pdb;
|
||||
}
|
||||
else if (string.Equals(extension, ".dll", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
resourceList = resourceData.assembly;
|
||||
}
|
||||
else if (string.Equals(assetType, "native", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
resourceList = resourceData.runtime;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This should include items such as XML doc files, which do not need to be recorded in the manifest.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!resourceList.ContainsKey(resourceName))
|
||||
{
|
||||
resourceList.Add(resourceName, $"sha256-{resource.GetMetadata("FileHash")}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ConfigurationFiles != null)
|
||||
{
|
||||
foreach (var configFile in ConfigurationFiles)
|
||||
{
|
||||
result.config.Add(Path.GetFileName(configFile.ItemSpec));
|
||||
}
|
||||
}
|
||||
|
||||
var serializer = new DataContractJsonSerializer(typeof(BootJsonData), new DataContractJsonSerializerSettings
|
||||
{
|
||||
UseSimpleDictionaryFormat = true
|
||||
});
|
||||
|
||||
using var writer = JsonReaderWriterFactory.CreateJsonWriter(output, Encoding.UTF8, ownsStream: false, indent: true);
|
||||
serializer.WriteObject(writer, result);
|
||||
}
|
||||
|
||||
private bool IsLazyLoadedAssembly(string fileName)
|
||||
{
|
||||
return LazyLoadedAssemblies != null && LazyLoadedAssemblies.Any(a => a.ItemSpec == fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
// 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.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization.Json;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Tasks
|
||||
{
|
||||
public partial class GenerateServiceWorkerAssetsManifest : Task
|
||||
{
|
||||
[Required]
|
||||
public ITaskItem[] Assets { get; set; }
|
||||
|
||||
public string Version { get; set; }
|
||||
|
||||
[Required]
|
||||
public string OutputPath { get; set; }
|
||||
|
||||
[Output]
|
||||
public string CalculatedVersion { get; set; }
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
using var fileStream = File.Create(OutputPath);
|
||||
CalculatedVersion = GenerateAssetManifest(fileStream);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal string GenerateAssetManifest(Stream stream)
|
||||
{
|
||||
var assets = new AssetsManifestFileEntry[Assets.Length];
|
||||
System.Threading.Tasks.Parallel.For(0, assets.Length, i =>
|
||||
{
|
||||
var item = Assets[i];
|
||||
var hash = item.GetMetadata("FileHash");
|
||||
var url = item.GetMetadata("AssetUrl");
|
||||
|
||||
if (string.IsNullOrEmpty(hash))
|
||||
{
|
||||
// Some files that are part of the service worker manifest may not have their hashes previously
|
||||
// calcualted. Calculate them at this time.
|
||||
using var sha = SHA256.Create();
|
||||
using var file = File.OpenRead(item.ItemSpec);
|
||||
var bytes = sha.ComputeHash(file);
|
||||
|
||||
hash = Convert.ToBase64String(bytes);
|
||||
}
|
||||
|
||||
assets[i] = new AssetsManifestFileEntry
|
||||
{
|
||||
hash = "sha256-" + hash,
|
||||
url = url,
|
||||
};
|
||||
});
|
||||
|
||||
var version = Version;
|
||||
if (string.IsNullOrEmpty(version))
|
||||
{
|
||||
// If a version isn't specified (which is likely the most common case), construct a Version by combining
|
||||
// the file names + hashes of all the inputs.
|
||||
|
||||
var combinedHash = string.Join(
|
||||
Environment.NewLine,
|
||||
assets.OrderBy(f => f.url, StringComparer.Ordinal).Select(f => f.hash));
|
||||
|
||||
using var sha = SHA256.Create();
|
||||
var bytes = sha.ComputeHash(Encoding.UTF8.GetBytes(combinedHash));
|
||||
version = Convert.ToBase64String(bytes).Substring(0, 8);
|
||||
}
|
||||
|
||||
var data = new AssetsManifestFile
|
||||
{
|
||||
version = version,
|
||||
assets = assets,
|
||||
};
|
||||
|
||||
using var streamWriter = new StreamWriter(stream, Encoding.UTF8, bufferSize: 50, leaveOpen: true);
|
||||
streamWriter.Write("self.assetsManifest = ");
|
||||
streamWriter.Flush();
|
||||
|
||||
using var jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(stream, Encoding.UTF8, ownsStream: false, indent: true);
|
||||
new DataContractJsonSerializer(typeof(AssetsManifestFile)).WriteObject(jsonWriter, data);
|
||||
jsonWriter.Flush();
|
||||
|
||||
streamWriter.WriteLine(";");
|
||||
|
||||
return version;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
<!--
|
||||
***********************************************************************************************
|
||||
Microsoft.NET.Sdk.Razor.Components.ServiceWorkerAssetsManifest.targets
|
||||
|
||||
WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
|
||||
created a backup copy. Incorrect changes to this file will make it
|
||||
impossible to load or build your projects from the command-line or the IDE.
|
||||
|
||||
Copyright (c) .NET Foundation. All rights reserved.
|
||||
***********************************************************************************************
|
||||
-->
|
||||
|
||||
<Project>
|
||||
<UsingTask TaskName="Microsoft.AspNetCore.Razor.Tasks.GenerateServiceWorkerAssetsManifest" AssemblyFile="$(RazorSdkBuildTasksAssembly)" />
|
||||
|
||||
<Target Name="_ComputeServiceWorkerAssets" BeforeTargets="ResolveStaticWebAssetsInputs">
|
||||
<PropertyGroup>
|
||||
<_ServiceWorkerAssetsManifestIntermediateOutputPath>$(IntermediateOutputPath)$(ServiceWorkerAssetsManifest)</_ServiceWorkerAssetsManifestIntermediateOutputPath>
|
||||
<_ServiceWorkerAssetsManifestFullPath>$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)/$(_ServiceWorkerAssetsManifestIntermediateOutputPath)'))</_ServiceWorkerAssetsManifestFullPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_ManifestStaticWebAsset Include="$(_ServiceWorkerAssetsManifestFullPath)">
|
||||
<SourceType></SourceType>
|
||||
<SourceId>$(PackageId)</SourceId>
|
||||
<ContentRoot>$([MSBuild]::NormalizeDirectory('$(TargetDir)wwwroot\'))</ContentRoot>
|
||||
<BasePath>$(StaticWebAssetBasePath)</BasePath>
|
||||
<RelativePath>$(ServiceWorkerAssetsManifest)</RelativePath>
|
||||
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
|
||||
</_ManifestStaticWebAsset>
|
||||
|
||||
<!-- Figure out where we're getting the content for each @(ServiceWorker) entry, depending on whether there's a PublishedContent value -->
|
||||
<_ServiceWorkerIntermediateFile Include="@(ServiceWorker->'$(IntermediateOutputPath)serviceworkers\%(Identity)')">
|
||||
<ContentSourcePath Condition="'%(_ServiceWorker.PublishedContent)' != ''">%(ServiceWorker.PublishedContent)</ContentSourcePath>
|
||||
<ContentSourcePath Condition="'%(_ServiceWorker.PublishedContent)' == ''">%(ServiceWorker.Identity)</ContentSourcePath>
|
||||
<OriginalPath>%(ServiceWorker.Identity)</OriginalPath>
|
||||
<TargetOutputPath>%(ServiceWorker.Identity)</TargetOutputPath>
|
||||
<TargetOutputPath Condition="$([System.String]::Copy('%(ServiceWorker.Identity)').Replace('\','/').StartsWith('wwwroot/'))">$([System.String]::Copy('%(ServiceWorker.Identity)').Substring(8))</TargetOutputPath>
|
||||
</_ServiceWorkerIntermediateFile>
|
||||
|
||||
<_ServiceWorkerStaticWebAsset Include="%(_ServiceWorkerIntermediateFile.FullPath)">
|
||||
<SourceType></SourceType>
|
||||
<SourceId>$(PackageId)</SourceId>
|
||||
<ContentRoot>$([MSBuild]::NormalizeDirectory('$(TargetDir)wwwroot\'))</ContentRoot>
|
||||
<BasePath>$(StaticWebAssetBasePath)</BasePath>
|
||||
<RelativePath>%(TargetOutputPath)</RelativePath>
|
||||
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
|
||||
</_ServiceWorkerStaticWebAsset>
|
||||
|
||||
<StaticWebAsset Include="
|
||||
@(_ManifestStaticWebAsset);
|
||||
@(_ServiceWorkerStaticWebAsset)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Target>
|
||||
|
||||
<Target Name="_WriteServiceWorkerAssetsManifest"
|
||||
DependsOnTargets="_ComputeServiceWorkerAssets;ResolveStaticWebAssetsInputs">
|
||||
|
||||
<ItemGroup>
|
||||
<_ServiceWorkItem Include="@(StaticWebAsset)" Exclude="$(_ServiceWorkerAssetsManifestFullPath);@(_ServiceWorkerStaticWebAsset)">
|
||||
<AssetUrl>$([System.String]::Copy('$([System.String]::Copy('%(StaticWebAsset.BasePath)').TrimEnd('/'))/%(StaticWebAsset.RelativePath)').Replace('\','/').TrimStart('/'))</AssetUrl>
|
||||
</_ServiceWorkItem>
|
||||
</ItemGroup>
|
||||
|
||||
<GenerateServiceWorkerAssetsManifest
|
||||
Version="$(ServiceWorkerAssetsManifestVersion)"
|
||||
Assets="@(_ServiceWorkItem)"
|
||||
OutputPath="$(_ServiceWorkerAssetsManifestIntermediateOutputPath)">
|
||||
<Output TaskParameter="CalculatedVersion" PropertyName="_ServiceWorkerAssetsManifestVersion" />
|
||||
</GenerateServiceWorkerAssetsManifest>
|
||||
|
||||
<Copy
|
||||
SourceFiles="%(_ServiceWorkerIntermediateFile.ContentSourcePath)"
|
||||
DestinationFiles="%(_ServiceWorkerIntermediateFile.Identity)" />
|
||||
|
||||
<WriteLinesToFile
|
||||
File="%(_ServiceWorkerIntermediateFile.Identity)"
|
||||
Lines="/* Manifest version: $(_ServiceWorkerAssetsManifestVersion) */"
|
||||
Condition="'$(_ServiceWorkerAssetsManifestVersion)' != ''" />
|
||||
|
||||
<ItemGroup>
|
||||
<FileWrites Include="@(_ServiceWorkerIntermediateFile)" />
|
||||
<FileWrites Include="$(_ServiceWorkerAssetsManifestIntermediateOutputPath)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Target>
|
||||
|
||||
<Target Name="_BlazorStaticAssetsCopyFilesToOutputDirectory" AfterTargets="CopyFilesToOutputDirectory" DependsOnTargets="_WriteServiceWorkerAssetsManifest">
|
||||
<Copy
|
||||
SourceFiles="@(_ManifestStaticWebAsset);@(_ServiceWorkerStaticWebAsset)"
|
||||
DestinationFiles="$(OutDir)wwwroot\%(RelativePath)"
|
||||
SkipUnchangedFiles="$(SkipCopyUnchangedFiles)"
|
||||
OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
|
||||
Retries="$(CopyRetryCount)"
|
||||
RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
|
||||
UseHardlinksIfPossible="$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)"
|
||||
UseSymboliclinksIfPossible="$(CreateSymbolicLinksForCopyFilesToOutputDirectoryIfPossible)"
|
||||
ErrorIfLinkFails="$(ErrorIfLinkFailsForCopyFilesToOutputDirectory)">
|
||||
|
||||
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
|
||||
</Copy>
|
||||
</Target>
|
||||
|
||||
<Target Name="_OmitServiceWorkerContent"
|
||||
BeforeTargets="AssignTargetPaths;ResolveCurrentProjectStaticWebAssetsInputs">
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Don't emit the service worker source files to the output -->
|
||||
<Content Remove="@(ServiceWorker)" />
|
||||
<Content Remove="@(ServiceWorker->'%(PublishedContent)')" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="_GenerateServiceWorkerFileForPublish"
|
||||
BeforeTargets="_BlazorCompressPublishFiles"
|
||||
AfterTargets="_ProcessPublishFilesForBlazor">
|
||||
|
||||
<PropertyGroup>
|
||||
<_ServiceWorkerAssetsManifestPublishIntermediateOutputPath>$(IntermediateOutputPath)publish-$(ServiceWorkerAssetsManifest)</_ServiceWorkerAssetsManifestPublishIntermediateOutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_ServiceWorkerIntermediatePublishFile Include="$(IntermediateOutputPath)serviceworkers\%(FileName).publish%(Extension)">
|
||||
<ContentSourcePath Condition="'%(ServiceWorker.PublishedContent)' != ''">%(ServiceWorker.PublishedContent)</ContentSourcePath>
|
||||
<ContentSourcePath Condition="'%(ServiceWorker.PublishedContent)' == ''">%(ServiceWorker.Identity)</ContentSourcePath>
|
||||
<RelativePath>%(ServiceWorker.Identity)</RelativePath>
|
||||
</_ServiceWorkerIntermediatePublishFile>
|
||||
|
||||
<_ServiceWorkerPublishFile Include="@(ResolvedFileToPublish)" Condition="$([System.String]::Copy('%(ResolvedFileToPublish.RelativePath)').Replace('\','/').StartsWith('wwwroot/'))">
|
||||
<AssetUrl>$([System.String]::Copy('%(ResolvedFileToPublish.RelativePath)').Replace('\','/').TrimStart('/'))</AssetUrl>
|
||||
<AssetUrl>$([System.String]::Copy('%(RelativePath)').Replace('\','/').Substring(8))</AssetUrl>
|
||||
</_ServiceWorkerPublishFile>
|
||||
</ItemGroup>
|
||||
|
||||
<GenerateServiceWorkerAssetsManifest
|
||||
Version="$(ServiceWorkerAssetsManifestVersion)"
|
||||
Assets="@(_ServiceWorkerPublishFile)"
|
||||
OutputPath="$(_ServiceWorkerAssetsManifestPublishIntermediateOutputPath)">
|
||||
|
||||
<Output TaskParameter="CalculatedVersion" PropertyName="_ServiceWorkerPublishAssetsManifestVersion" />
|
||||
</GenerateServiceWorkerAssetsManifest>
|
||||
|
||||
<Copy SourceFiles="%(_ServiceWorkerIntermediatePublishFile.ContentSourcePath)"
|
||||
DestinationFiles="%(_ServiceWorkerIntermediatePublishFile.Identity)" />
|
||||
|
||||
<WriteLinesToFile
|
||||
File="%(_ServiceWorkerIntermediatePublishFile.Identity)"
|
||||
Lines="/* Manifest version: $(_ServiceWorkerPublishAssetsManifestVersion) */" />
|
||||
|
||||
<ItemGroup>
|
||||
<ResolvedFileToPublish
|
||||
Include="@(_ServiceWorkerIntermediatePublishFile)"
|
||||
CopyToPublishDirectory="PreserveNewest"
|
||||
RelativePath="%(_ServiceWorkerIntermediatePublishFile.RelativePath)"
|
||||
ExcludeFromSingleFile="true" />
|
||||
|
||||
<ResolvedFileToPublish
|
||||
Include="$(_ServiceWorkerAssetsManifestPublishIntermediateOutputPath)"
|
||||
CopyToPublishDirectory="PreserveNewest"
|
||||
RelativePath="wwwroot\$(ServiceWorkerAssetsManifest)"
|
||||
ExcludeFromSingleFile="true" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,550 +0,0 @@
|
|||
<!--
|
||||
***********************************************************************************************
|
||||
Microsoft.NET.Sdk.Razor.Components.Wasm.targets
|
||||
|
||||
WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
|
||||
created a backup copy. Incorrect changes to this file will make it
|
||||
impossible to load or build your projects from the command-line or the IDE.
|
||||
|
||||
Copyright (c) .NET Foundation. All rights reserved.
|
||||
***********************************************************************************************
|
||||
-->
|
||||
|
||||
<Project ToolsVersion="14.0">
|
||||
<UsingTask TaskName="Microsoft.AspNetCore.Razor.Tasks.GenerateBlazorWebAssemblyBootJson" AssemblyFile="$(RazorSdkBuildTasksAssembly)" />
|
||||
<UsingTask TaskName="Microsoft.AspNetCore.Razor.Tasks.BlazorWriteSatelliteAssemblyFile" AssemblyFile="$(RazorSdkBuildTasksAssembly)" />
|
||||
<UsingTask TaskName="Microsoft.AspNetCore.Razor.Tasks.BlazorReadSatelliteAssemblyFile" AssemblyFile="$(RazorSdkBuildTasksAssembly)" />
|
||||
<UsingTask TaskName="Microsoft.AspNetCore.Razor.Tasks.BrotliCompress" AssemblyFile="$(RazorSdkBuildTasksAssembly)" />
|
||||
<UsingTask TaskName="Microsoft.AspNetCore.Razor.Tasks.GzipCompress" AssemblyFile="$(RazorSdkBuildTasksAssembly)" />
|
||||
<UsingTask TaskName="Microsoft.AspNetCore.Razor.Tasks.CreateBlazorTrimmerRootDescriptorFile" AssemblyFile="$(RazorSdkBuildTasksAssembly)" />
|
||||
|
||||
<PropertyGroup>
|
||||
<SelfContained>true</SelfContained>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
|
||||
<!-- Trimmer defaults -->
|
||||
<PublishTrimmed Condition="'$(PublishTrimmed)' == ''">true</PublishTrimmed>
|
||||
<TrimMode Condition="'$(TrimMode)' == ''">link</TrimMode>
|
||||
<TrimmerRemoveSymbols Condition="'$(TrimmerRemoveSymbols)' == ''">false</TrimmerRemoveSymbols>
|
||||
|
||||
<!-- Runtime feature defaults to trim unnecessary code -->
|
||||
<EventSourceSupport Condition="'$(EventSourceSupport)' == ''">false</EventSourceSupport>
|
||||
<UseSystemResourceKeys Condition="'$(UseSystemResourceKeys)' == ''">true</UseSystemResourceKeys>
|
||||
<EnableUnsafeUTF7Encoding Condition="'$(EnableUnsafeUTF7Encoding)' == ''">false</EnableUnsafeUTF7Encoding>
|
||||
<HttpActivityPropagationSupport Condition="'$(HttpActivityPropagationSupport)' == ''">false</HttpActivityPropagationSupport>
|
||||
<DebuggerSupport Condition="'$(DebuggerSupport)' == '' and '$(Configuration)' == 'Release'">false</DebuggerSupport>
|
||||
|
||||
<StaticWebAssetBasePath Condition="'$(StaticWebAssetBasePath)' == ''">/</StaticWebAssetBasePath>
|
||||
<BlazorCacheBootResources Condition="'$(BlazorCacheBootResources)' == ''">true</BlazorCacheBootResources>
|
||||
|
||||
<!-- Turn off parts of the build that do not apply to WASM projects -->
|
||||
<GenerateDependencyFile>false</GenerateDependencyFile>
|
||||
<GenerateRuntimeConfigurationFiles>false</GenerateRuntimeConfigurationFiles>
|
||||
<PreserveCompilationContext>false</PreserveCompilationContext>
|
||||
<PreserveCompilationReferences>false</PreserveCompilationReferences>
|
||||
<AddRazorSupportForMvc>false</AddRazorSupportForMvc>
|
||||
<OutputType>exe</OutputType>
|
||||
|
||||
<!-- Internal properties -->
|
||||
<_BlazorOutputPath>wwwroot\_framework\</_BlazorOutputPath>
|
||||
<_BlazorSatelliteAssemblyCacheFile>$(IntermediateOutputPath)blazor.satelliteasm.props</_BlazorSatelliteAssemblyCacheFile>
|
||||
|
||||
<!-- Workaround for https://github.com/dotnet/sdk/issues/12114-->
|
||||
<PublishDir Condition="'$(AppendRuntimeIdentifierToOutputPath)' != 'true' AND '$(PublishDir)' == '$(OutputPath)$(RuntimeIdentifier)\$(PublishDirName)\'">$(OutputPath)$(PublishDirName)\</PublishDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<FrameworkReference Remove="Microsoft.AspNetCore.App" />
|
||||
<KnownFrameworkReference Remove="Microsoft.AspNetCore.App" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="Microsoft.NET.Sdk.Razor.Components.ServiceWorkerAssetsManifest.targets" Condition="'$(ServiceWorkerAssetsManifest)' != ''" />
|
||||
|
||||
<Target Name="_ScrambleDotnetJsFileName" AfterTargets="ResolveRuntimePackAssets">
|
||||
<!--
|
||||
We want the dotnet.js file output to have a version to better work with caching. We'll append the runtime version to the file name as soon as file has been discovered.
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<_DotNetJsVersion>$(BundledNETCoreAppPackageVersion)</_DotNetJsVersion>
|
||||
<_DotNetJsVersion Condition="'$(RuntimeFrameworkVersion)' != ''">$(RuntimeFrameworkVersion)</_DotNetJsVersion>
|
||||
<_BlazorDotnetJsFileName>dotnet.$(_DotNetJsVersion).js</_BlazorDotnetJsFileName>
|
||||
<_BlazorDotNetJsFilePath>$(IntermediateOutputPath)$(_BlazorDotnetJsFileName)</_BlazorDotNetJsFilePath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_DotNetJsItem Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.DestinationSubPath)' == 'dotnet.js' AND '%(ReferenceCopyLocalPaths.AssetType)' == 'native'" />
|
||||
</ItemGroup>
|
||||
|
||||
<Copy
|
||||
SourceFiles="@(_DotNetJsItem)"
|
||||
DestinationFiles="$(_BlazorDotNetJsFilePath)"
|
||||
SkipUnchangedFiles="true"
|
||||
OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)" />
|
||||
|
||||
<ItemGroup Condition="'@(_DotNetJsItem->Count())' != '0'">
|
||||
<ReferenceCopyLocalPaths
|
||||
Include="$(_BlazorDotNetJsFilePath)"
|
||||
AssetType="native"
|
||||
CopyLocal="true"
|
||||
DestinationSubPath="$(_BlazorDotnetJsFileName)" />
|
||||
|
||||
<ReferenceCopyLocalPaths Remove="@(_DotNetJsItem)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="_ResolveBlazorWasmOutputs" DependsOnTargets="ResolveReferences;PrepareResourceNames;ComputeIntermediateSatelliteAssemblies">
|
||||
<!--
|
||||
Calculates the outputs and the paths for Blazor WASM. This target is invoked frequently and should perform minimal work.
|
||||
-->
|
||||
|
||||
<ItemGroup>
|
||||
<_BlazorJSFile Include="$(BlazorWebAssemblyJSPath)" />
|
||||
<_BlazorJSFile Include="$(BlazorWebAssemblyJSMapPath)" Condition="Exists('$(BlazorWebAssemblyJSMapPath)')" />
|
||||
|
||||
<_BlazorConfigFile Include="wwwroot\appsettings*.json" />
|
||||
|
||||
<!-- Clear out temporary build artifacts that the runtime packages -->
|
||||
<ReferenceCopyLocalPaths Remove="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.Extension)' == '.a'" />
|
||||
|
||||
<!--
|
||||
ReferenceCopyLocalPaths includes satellite assemblies from referenced projects but are inexpicably missing
|
||||
any metadata that might allow them to be differentiated. We'll explicitly add those
|
||||
to _BlazorOutputWithTargetPath so that satellite assemblies from packages, the current project and referenced project
|
||||
are all treated the same.
|
||||
-->
|
||||
|
||||
<_BlazorCopyLocalPath
|
||||
Include="@(ReferenceCopyLocalPaths)"
|
||||
Exclude="@(ReferenceSatellitePaths)"/>
|
||||
|
||||
<_BlazorCopyLocalPath Include="@(IntermediateSatelliteAssembliesWithTargetPath)">
|
||||
<DestinationSubDirectory>%(IntermediateSatelliteAssembliesWithTargetPath.Culture)\</DestinationSubDirectory>
|
||||
</_BlazorCopyLocalPath>
|
||||
|
||||
<_BlazorOutputWithTargetPath Include="
|
||||
@(_BlazorCopyLocalPath);
|
||||
@(IntermediateAssembly);
|
||||
@(_DebugSymbolsIntermediatePath);
|
||||
@(_BlazorJSFile)" />
|
||||
|
||||
<_BlazorOutputWithTargetPath Include="@(ReferenceSatellitePaths)">
|
||||
<Culture>$([System.String]::Copy('%(ReferenceSatellitePaths.DestinationSubDirectory)').Trim('\').Trim('/'))</Culture>
|
||||
</_BlazorOutputWithTargetPath>
|
||||
</ItemGroup>
|
||||
|
||||
<!--
|
||||
BuildingProject=false is typically set for referenced projects when building inside VisualStudio.
|
||||
|
||||
When building with BuildingProject=false, satellite assemblies do not get resolved (the ones for the current project and the one for
|
||||
referenced project). Satellite assemblies from packages get resolved.
|
||||
To workaround this, we'll cache metadata during a regular build, and rehydrate from it when BuildingProject=false.
|
||||
-->
|
||||
<BlazorReadSatelliteAssemblyFile
|
||||
ReadFile="$(_BlazorSatelliteAssemblyCacheFile)"
|
||||
Condition="'$(BuildingProject)' != 'true' AND EXISTS('$(_BlazorSatelliteAssemblyCacheFile)')">
|
||||
<Output TaskParameter="SatelliteAssembly" ItemName="_BlazorReadSatelliteAssembly" />
|
||||
</BlazorReadSatelliteAssemblyFile>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- We've imported a previously Cacheed file. Let's turn in to a _BlazorOutputWithTargetPath -->
|
||||
<_BlazorOutputWithTargetPath
|
||||
Include="@(_BlazorReadSatelliteAssembly)"
|
||||
Exclude="@(_BlazorOutputWithTargetPath)"
|
||||
Condition="'@(_BlazorReadSatelliteAssembly->Count())' != '0'" />
|
||||
|
||||
<!-- Calculate the target path -->
|
||||
<_BlazorOutputWithTargetPath
|
||||
TargetPath="$(_BlazorOutputPath)%(_BlazorOutputWithTargetPath.DestinationSubDirectory)%(FileName)%(Extension)"
|
||||
Condition="'%(__BlazorOutputWithTargetPath.TargetPath)' == ''" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="_ProcessBlazorWasmOutputs" DependsOnTargets="_ResolveBlazorWasmOutputs">
|
||||
<PropertyGroup>
|
||||
<_BlazorBuildGZipCompressDirectory>$(IntermediateOutputPath)build-gz\</_BlazorBuildGZipCompressDirectory>
|
||||
</PropertyGroup>
|
||||
|
||||
<!--
|
||||
Compress referenced binaries using GZip during build. This skips files such as the project's assemblies
|
||||
that change from build to build. Runtime assets contribute to the bulk of the download size. Compressing it
|
||||
has the most benefit while avoiding any ongoing costs to the dev inner loop.
|
||||
-->
|
||||
<ItemGroup>
|
||||
<_GzipFileToCompressForBuild
|
||||
Include="@(ReferenceCopyLocalPaths)"
|
||||
RelativePath="$(_BlazorOutputPath)%(ReferenceCopyLocalPaths.DestinationSubDirectory)%(FileName)%(Extension)"
|
||||
Condition="'%(Extension)' == '.dll' or '%(ReferenceCopyLocalPaths.AssetType)' == 'native'" />
|
||||
</ItemGroup>
|
||||
|
||||
<GZipCompress
|
||||
FilesToCompress="@(_GzipFileToCompressForBuild)"
|
||||
OutputDirectory="$(_BlazorBuildGZipCompressDirectory)">
|
||||
|
||||
<Output TaskParameter="CompressedFiles" ItemName="_BlazorBuildGZipCompressedFile" />
|
||||
<Output TaskParameter="CompressedFiles" ItemName="FileWrites" />
|
||||
</GZipCompress>
|
||||
|
||||
<ItemGroup>
|
||||
<_BlazorWriteSatelliteAssembly Include="@(_BlazorOutputWithTargetPath->HasMetadata('Culture'))" />
|
||||
|
||||
<!-- Retarget ReferenceCopyLocalPaths to copy to the wwwroot directory -->
|
||||
<ReferenceCopyLocalPaths DestinationSubDirectory="$(_BlazorOutputPath)%(ReferenceCopyLocalPaths.DestinationSubDirectory)" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- A missing blazor.webassembly.js is our packaging error. Produce an error so it's discovered early. -->
|
||||
<Error
|
||||
Text="Unable to find BlazorWebAssembly JS files. This usually indicates a packaging error."
|
||||
Code="RAZORSDK1007"
|
||||
Condition="'@(_BlazorJSFile->Count())' == '0'" />
|
||||
|
||||
<!--
|
||||
When building with BuildingProject=false, satellite assemblies do not get resolved (the ones for the current project and the one for
|
||||
referenced project). BuildingProject=false is typically set for referenced projects when building inside VisualStudio.
|
||||
To workaround this, we'll cache metadata during a regular build, and rehydrate from it when BuildingProject=false.
|
||||
-->
|
||||
|
||||
<BlazorWriteSatelliteAssemblyFile
|
||||
SatelliteAssembly="@(_BlazorWriteSatelliteAssembly)"
|
||||
WriteFile="$(_BlazorSatelliteAssemblyCacheFile)"
|
||||
Condition="'$(BuildingProject)' == 'true' AND '@(_BlazorWriteSatelliteAssembly->Count())' != '0'" />
|
||||
|
||||
<Delete
|
||||
Files="$(_BlazorSatelliteAssemblyCacheFile)"
|
||||
Condition="'$(BuildingProject)' == 'true' AND '@(_BlazorWriteSatelliteAssembly->Count())' == '0' and EXISTS('$(_BlazorSatelliteAssemblyCacheFile)')" />
|
||||
|
||||
<ItemGroup>
|
||||
<FileWrites Include="$(_BlazorSatelliteAssemblyCacheFile)" Condition="Exists('$(_BlazorSatelliteAssemblyCacheFile)')" />
|
||||
</ItemGroup>
|
||||
|
||||
<GetFileHash Files="@(_BlazorOutputWithTargetPath)" Algorithm="SHA256" HashEncoding="base64">
|
||||
<Output TaskParameter="Items" ItemName="_BlazorOutputWithHash" />
|
||||
</GetFileHash>
|
||||
</Target>
|
||||
|
||||
<PropertyGroup>
|
||||
<PrepareForRunDependsOn>
|
||||
_BlazorWasmPrepareForRun;
|
||||
$(PrepareForRunDependsOn)
|
||||
</PrepareForRunDependsOn>
|
||||
|
||||
<GetCurrentProjectStaticWebAssetsDependsOn>
|
||||
$(GetCurrentProjectStaticWebAssetsDependsOn);
|
||||
_BlazorWasmPrepareForRun;
|
||||
</GetCurrentProjectStaticWebAssetsDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="_BlazorWasmPrepareForRun" DependsOnTargets="_ProcessBlazorWasmOutputs">
|
||||
<PropertyGroup>
|
||||
<_BlazorBuildBootJsonPath>$(IntermediateOutputPath)blazor.boot.json</_BlazorBuildBootJsonPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<GenerateBlazorWebAssemblyBootJson
|
||||
AssemblyPath="@(IntermediateAssembly)"
|
||||
Resources="@(_BlazorOutputWithHash)"
|
||||
DebugBuild="true"
|
||||
LinkerEnabled="false"
|
||||
CacheBootResources="$(BlazorCacheBootResources)"
|
||||
OutputPath="$(_BlazorBuildBootJsonPath)"
|
||||
ConfigurationFiles="@(_BlazorConfigFile)"
|
||||
LazyLoadedAssemblies="@(BlazorWebAssemblyLazyLoad)" />
|
||||
|
||||
<ItemGroup>
|
||||
<FileWrites Include="$(OutDir)$(_BlazorOutputPath)blazor.boot.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_BlazorWebAssemblyStaticWebAsset Include="$(_BlazorBuildBootJsonPath)">
|
||||
<SourceId>$(PackageId)</SourceId>
|
||||
<SourceType></SourceType>
|
||||
<ContentRoot>$([MSBuild]::NormalizeDirectory('$(TargetDir)wwwroot\'))</ContentRoot>
|
||||
<BasePath>$(StaticWebAssetBasePath)</BasePath>
|
||||
<RelativePath>_framework/blazor.boot.json</RelativePath>
|
||||
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
|
||||
</_BlazorWebAssemblyStaticWebAsset>
|
||||
|
||||
<_BlazorWebAssemblyStaticWebAsset Include="@(_BlazorOutputWithHash)">
|
||||
<SourceId>$(PackageId)</SourceId>
|
||||
<SourceType></SourceType>
|
||||
<ContentRoot>$([MSBuild]::NormalizeDirectory('$(TargetDir)wwwroot\'))</ContentRoot>
|
||||
<BasePath>$(StaticWebAssetBasePath)</BasePath>
|
||||
<RelativePath>$([System.String]::Copy('%(_BlazorOutputWithHash.TargetPath)').Replace('\','/').Substring(8))</RelativePath>
|
||||
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
|
||||
</_BlazorWebAssemblyStaticWebAsset>
|
||||
|
||||
<_BlazorWebAssemblyStaticWebAsset Include="@(_BlazorBuildGZipCompressedFile)">
|
||||
<SourceId>$(PackageId)</SourceId>
|
||||
<SourceType></SourceType>
|
||||
<ContentRoot>$([MSBuild]::NormalizeDirectory('$(TargetDir)wwwroot\'))</ContentRoot>
|
||||
<BasePath>$(StaticWebAssetBasePath)</BasePath>
|
||||
<RelativePath>$([System.String]::Copy('%(_BlazorBuildGZipCompressedFile.RelativePath)').Replace('\','/').Substring(8))</RelativePath>
|
||||
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
|
||||
</_BlazorWebAssemblyStaticWebAsset>
|
||||
|
||||
<StaticWebAsset Include="@(_BlazorWebAssemblyStaticWebAsset)" />
|
||||
<_ExternalStaticWebAsset Include="@(_BlazorWebAssemblyStaticWebAsset)" SourceType="Generated" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<!-- Mimics the behavior of CopyFilesToOutputDirectory. We simply copy relevant build outputs to the wwwroot directory -->
|
||||
<Target Name="_BlazorCopyFilesToOutputDirectory" AfterTargets="CopyFilesToOutputDirectory">
|
||||
<Copy
|
||||
SourceFiles="@(IntermediateAssembly)"
|
||||
DestinationFolder="$(OutDir)$(_BlazorOutputPath)"
|
||||
SkipUnchangedFiles="$(SkipCopyUnchangedFiles)"
|
||||
OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
|
||||
Retries="$(CopyRetryCount)"
|
||||
RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
|
||||
UseHardlinksIfPossible="$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)"
|
||||
UseSymboliclinksIfPossible="$(CreateSymbolicLinksForCopyFilesToOutputDirectoryIfPossible)"
|
||||
ErrorIfLinkFails="$(ErrorIfLinkFailsForCopyFilesToOutputDirectory)"
|
||||
Condition="'$(CopyBuildOutputToOutputDirectory)' == 'true' and '$(SkipCopyBuildProduct)' != 'true'">
|
||||
|
||||
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
|
||||
</Copy>
|
||||
|
||||
<Message Importance="High" Text="$(MSBuildProjectName) (Blazor output) -> $(TargetDir)wwwroot" Condition="'$(CopyBuildOutputToOutputDirectory)' == 'true' and '$(SkipCopyBuildProduct)'!='true'" />
|
||||
|
||||
<Copy
|
||||
SourceFiles="@(_DebugSymbolsIntermediatePath)"
|
||||
DestinationFolder="$(OutDir)$(_BlazorOutputPath)"
|
||||
SkipUnchangedFiles="$(SkipCopyUnchangedFiles)"
|
||||
OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
|
||||
Retries="$(CopyRetryCount)"
|
||||
RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
|
||||
UseHardlinksIfPossible="$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)"
|
||||
UseSymboliclinksIfPossible="$(CreateSymbolicLinksForCopyFilesToOutputDirectoryIfPossible)"
|
||||
ErrorIfLinkFails="$(ErrorIfLinkFailsForCopyFilesToOutputDirectory)"
|
||||
Condition="'$(_DebugSymbolsProduced)'=='true' and '$(SkipCopyingSymbolsToOutputDirectory)' != 'true' and '$(CopyOutputSymbolsToOutputDirectory)'=='true'">
|
||||
|
||||
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
|
||||
</Copy>
|
||||
|
||||
<Copy
|
||||
SourceFiles="@(IntermediateSatelliteAssembliesWithTargetPath)"
|
||||
DestinationFiles="@(IntermediateSatelliteAssembliesWithTargetPath->'$(OutDir)$(_BlazorOutputPath)%(Culture)\$(TargetName).resources.dll')"
|
||||
SkipUnchangedFiles="$(SkipCopyUnchangedFiles)"
|
||||
OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
|
||||
Retries="$(CopyRetryCount)"
|
||||
RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
|
||||
UseHardlinksIfPossible="$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)"
|
||||
UseSymboliclinksIfPossible="$(CreateSymbolicLinksForCopyFilesToOutputDirectoryIfPossible)"
|
||||
ErrorIfLinkFails="$(ErrorIfLinkFailsForCopyFilesToOutputDirectory)"
|
||||
Condition="'@(IntermediateSatelliteAssembliesWithTargetPath)' != ''" >
|
||||
|
||||
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
|
||||
</Copy>
|
||||
|
||||
<Copy
|
||||
SourceFiles="@(_BlazorJSFile);$(_BlazorBuildBootJsonPath)"
|
||||
DestinationFolder="$(OutDir)$(_BlazorOutputPath)"
|
||||
SkipUnchangedFiles="$(SkipCopyUnchangedFiles)"
|
||||
OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
|
||||
Retries="$(CopyRetryCount)"
|
||||
RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
|
||||
UseHardlinksIfPossible="$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)"
|
||||
UseSymboliclinksIfPossible="$(CreateSymbolicLinksForCopyFilesToOutputDirectoryIfPossible)"
|
||||
ErrorIfLinkFails="$(ErrorIfLinkFailsForCopyFilesToOutputDirectory)">
|
||||
|
||||
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
|
||||
</Copy>
|
||||
|
||||
<Copy
|
||||
SourceFiles="@(_BlazorBuildGZipCompressedFile)"
|
||||
DestinationFiles="@(_BlazorBuildGZipCompressedFile->'$(OutDir)%(RelativePath)')"
|
||||
SkipUnchangedFiles="$(SkipCopyUnchangedFiles)"
|
||||
OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
|
||||
Retries="$(CopyRetryCount)"
|
||||
RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
|
||||
UseHardlinksIfPossible="$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)"
|
||||
UseSymboliclinksIfPossible="$(CreateSymbolicLinksForCopyFilesToOutputDirectoryIfPossible)"
|
||||
ErrorIfLinkFails="$(ErrorIfLinkFailsForCopyFilesToOutputDirectory)">
|
||||
|
||||
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
|
||||
</Copy>
|
||||
</Target>
|
||||
|
||||
<Target Name="_BlazorWasmPrepareForLink" BeforeTargets="PrepareForILLink">
|
||||
<PropertyGroup>
|
||||
<_BlazorTypeGranularTrimmerDescriptorFile>$(IntermediateOutputPath)typegranularity.trimmerdescriptor.xml</_BlazorTypeGranularTrimmerDescriptorFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_BlazorTypeGranularAssembly
|
||||
Include="@(ManagedAssemblyToLink)"
|
||||
Condition="'%(Extension)' == '.dll' AND ($([System.String]::Copy('%(Filename)').StartsWith('Microsoft.AspNetCore.')) or $([System.String]::Copy('%(Filename)').StartsWith('Microsoft.Extensions.')))">
|
||||
<Required>false</Required>
|
||||
<Preserve>all</Preserve>
|
||||
</_BlazorTypeGranularAssembly>
|
||||
|
||||
<ManagedAssemblyToLink
|
||||
IsTrimmable="true"
|
||||
Condition="'%(Extension)' == '.dll' AND ($([System.String]::Copy('%(Filename)').StartsWith('Microsoft.AspNetCore.')) or $([System.String]::Copy('%(Filename)').StartsWith('Microsoft.Extensions.')))" />
|
||||
</ItemGroup>
|
||||
|
||||
<CreateBlazorTrimmerRootDescriptorFile
|
||||
Assemblies="@(_BlazorTypeGranularAssembly)"
|
||||
TrimmerFile="$(_BlazorTypeGranularTrimmerDescriptorFile)" />
|
||||
|
||||
<ItemGroup>
|
||||
<TrimmerRootDescriptor Include="$(_BlazorTypeGranularTrimmerDescriptorFile)" />
|
||||
|
||||
<FileWrites Include="$(_BlazorTypeGranularTrimmerDescriptorFile)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="_ProcessPublishFilesForBlazor" DependsOnTargets="_ResolveBlazorWasmOutputs" AfterTargets="ILLink">
|
||||
|
||||
<!--
|
||||
ResolvedFileToPublish.Culture is missing for satellite assemblies from project references.
|
||||
Since we need the culture to correctly generate blazor.boot.json, we cross-reference the culture we calculate as part of _ResolveBlazorWasmOutputs
|
||||
-->
|
||||
<JoinItems Left="@(ResolvedFileToPublish)"
|
||||
Right="@(_BlazorOutputWithTargetPath->HasMetadata('Culture'))"
|
||||
LeftMetadata="*"
|
||||
RightMetadata="Culture"
|
||||
ItemSpecToUse="Left">
|
||||
<Output TaskParameter="JoinResult" ItemName="_ResolvedSatelliteToPublish" />
|
||||
</JoinItems>
|
||||
|
||||
<ItemGroup>
|
||||
<ResolvedFileToPublish Remove="@(_ResolvedSatelliteToPublish)" />
|
||||
<ResolvedFileToPublish Include="@(_ResolvedSatelliteToPublish)" />
|
||||
|
||||
<ResolvedFileToPublish Remove="@(ResolvedFileToPublish)" Condition="'%(Extension)' == '.a'" />
|
||||
|
||||
<!-- Remove dotnet.js from publish output -->
|
||||
<ResolvedFileToPublish Remove="@(ResolvedFileToPublish)" Condition="'%(ResolvedFileToPublish.RelativePath)' == 'dotnet.js'" />
|
||||
|
||||
<!-- Retarget so that items are published to the wwwroot directory -->
|
||||
<ResolvedFileToPublish
|
||||
RelativePath="$(_BlazorOutputPath)%(ResolvedFileToPublish.RelativePath)"
|
||||
Condition="'%(ResolvedFileToPublish.RelativePath)' != 'web.config' AND !$([System.String]::Copy('%(ResolvedFileToPublish.RelativePath)').Replace('\','/').StartsWith('wwwroot/'))" />
|
||||
|
||||
<!-- Remove pdbs from the publish output -->
|
||||
<ResolvedFileToPublish Remove="@(ResolvedFileToPublish)" Condition="'$(DebuggerSupport)' == 'false' AND '%(Extension)' == '.pdb'" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'@(ResolvedFileToPublish->AnyHaveMetadataValue('RelativePath', 'web.config'))' != 'true'">
|
||||
<ResolvedFileToPublish
|
||||
Include="$(MSBuildThisFileDirectory)BlazorWasm.web.config"
|
||||
ExcludeFromSingleFile="true"
|
||||
CopyToPublishDirectory="PreserveNewest"
|
||||
RelativePath="web.config" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Generate the publish boot json -->
|
||||
<ItemGroup>
|
||||
<_BlazorPublishBootResource
|
||||
Include="@(ResolvedFileToPublish)"
|
||||
Condition="$([System.String]::Copy('%(RelativePath)').Replace('\','/').StartsWith('wwwroot/_framework')) AND '%(Extension)' != '.a'" />
|
||||
</ItemGroup>
|
||||
|
||||
<GetFileHash Files="@(_BlazorPublishBootResource)" Algorithm="SHA256" HashEncoding="base64">
|
||||
<Output TaskParameter="Items" ItemName="_BlazorPublishBootResourceWithHash" />
|
||||
</GetFileHash>
|
||||
|
||||
<GenerateBlazorWebAssemblyBootJson
|
||||
AssemblyPath="@(IntermediateAssembly)"
|
||||
Resources="@(_BlazorPublishBootResourceWithHash)"
|
||||
DebugBuild="false"
|
||||
LinkerEnabled="$(PublishTrimmed)"
|
||||
CacheBootResources="$(BlazorCacheBootResources)"
|
||||
OutputPath="$(IntermediateOutputPath)blazor.publish.boot.json"
|
||||
ConfigurationFiles="@(_BlazorConfigFile)"
|
||||
LazyLoadedAssemblies="@(BlazorWebAssemblyLazyLoad)" />
|
||||
|
||||
<ItemGroup>
|
||||
<ResolvedFileToPublish
|
||||
Include="$(IntermediateOutputPath)blazor.publish.boot.json"
|
||||
RelativePath="$(_BlazorOutputPath)blazor.boot.json" />
|
||||
|
||||
<ResolvedFileToPublish
|
||||
Include="@(_BlazorJSFile)"
|
||||
RelativePath="$(_BlazorOutputPath)%(FileName)%(Extension)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="_BlazorCompressPublishFiles" AfterTargets="_ProcessPublishFilesForBlazor" Condition="'$(BlazorEnableCompression)' != 'false'">
|
||||
<PropertyGroup>
|
||||
<_CompressedFileOutputPath>$(IntermediateOutputPath)compress\</_CompressedFileOutputPath>
|
||||
<_BlazorWebAssemblyBrotliIncremental>true</_BlazorWebAssemblyBrotliIncremental>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_FileToCompress
|
||||
Include="@(ResolvedFileToPublish)"
|
||||
Condition="$([System.String]::Copy('%(ResolvedFileToPublish.RelativePath)').Replace('\','/').StartsWith('wwwroot/'))" />
|
||||
</ItemGroup>
|
||||
|
||||
<Message Text="Compressing Blazor WebAssembly publish artifacts. This may take a while..." Importance="High" />
|
||||
|
||||
<MakeDir Directories="$(_CompressedFileOutputPath)" Condition="!Exists('$(_CompressedFileOutputPath)')" />
|
||||
|
||||
<BrotliCompress
|
||||
OutputDirectory="$(_CompressedFileOutputPath)"
|
||||
FilesToCompress="@(_FileToCompress)"
|
||||
CompressionLevel="$(_BlazorBrotliCompressionLevel)"
|
||||
SkipIfOutputIsNewer="$(_BlazorWebAssemblyBrotliIncremental)"
|
||||
ToolAssembly="$(_RazorSdkToolAssembly)">
|
||||
|
||||
<Output TaskParameter="CompressedFiles" ItemName="_BrotliCompressedFile" />
|
||||
<Output TaskParameter="CompressedFiles" ItemName="FileWrites" />
|
||||
</BrotliCompress>
|
||||
|
||||
<GZipCompress
|
||||
OutputDirectory="$(_CompressedFileOutputPath)"
|
||||
FilesToCompress="@(_FileToCompress)">
|
||||
|
||||
<Output TaskParameter="CompressedFiles" ItemName="_BlazorPublishGZipCompressedFile" />
|
||||
<Output TaskParameter="CompressedFiles" ItemName="FileWrites" />
|
||||
</GZipCompress>
|
||||
|
||||
<ItemGroup>
|
||||
<ResolvedFileToPublish Include="@(_BrotliCompressedFile)" />
|
||||
<ResolvedFileToPublish Include="@(_BlazorPublishGZipCompressedFile)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="_SetupPublishSemaphore" BeforeTargets="PrepareForPublish">
|
||||
<PropertyGroup>
|
||||
<!--
|
||||
Add marker that indicates Blazor WASM is doing a publish. This is used to identify when GetCopyToPublishDirectoryItems
|
||||
is invoked as a result of a P2P reference.
|
||||
-->
|
||||
<_PublishingBlazorWasmProject>true</_PublishingBlazorWasmProject>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="_GetBlazorWasmFilesForPublishInner"
|
||||
DependsOnTargets="_ResolveBlazorWasmOutputs;ComputeFilesToPublish"
|
||||
Returns="@(ResolvedFileToPublish)" />
|
||||
|
||||
<Target Name="_GetBlazorWasmFilesForPublish" BeforeTargets="GetCopyToPublishDirectoryItems">
|
||||
<MSBuild
|
||||
Projects="$(MSBuildProjectFullPath)"
|
||||
Targets="_GetBlazorWasmFilesForPublishInner"
|
||||
Properties="BuildProjectReferences=false;ResolveAssemblyReferencesFindRelatedSatellites=true;_PublishingBlazorWasmProject=true"
|
||||
RemoveProperties="NoBuild;RuntimeIdentifier"
|
||||
BuildInParallel="$(BuildInParallel)"
|
||||
Condition="'$(_PublishingBlazorWasmProject)' != 'true'">
|
||||
|
||||
<Output TaskParameter="TargetOutputs" ItemName="_ResolvedFileToPublish" />
|
||||
</MSBuild>
|
||||
|
||||
<ItemGroup>
|
||||
<AllPublishItemsFullPathWithTargetPath Include="@(_ResolvedFileToPublish->'%(FullPath)')">
|
||||
<TargetPath>%(RelativePath)</TargetPath>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</AllPublishItemsFullPathWithTargetPath>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="_BlazorApplyLinkPreferencesToContent" BeforeTargets="AssignTargetPaths;ResolveCurrentProjectStaticWebAssetsInputs;ResolveStaticWebAssetsInputs" Returns="@(Content)">
|
||||
<ItemGroup>
|
||||
<Content
|
||||
Condition="'%(Content.Link)' != '' AND '%(Content.CopyToPublishDirectory)' == '' AND $([System.String]::Copy('%(Content.Link)').Replace('\','/').StartsWith('wwwroot/'))"
|
||||
CopyToPublishDirectory="PreserveNewest" />
|
||||
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
||||
|
|
@ -58,7 +58,7 @@ Integration with static web assets:
|
|||
<_ScopedCssExtension>.rz.scp.css</_ScopedCssExtension>
|
||||
<ResolveStaticWebAssetsInputsDependsOn>$(ResolveStaticWebAssetsInputsDependsOn);_CollectAllScopedCssAssets;AddScopedCssBundle</ResolveStaticWebAssetsInputsDependsOn>
|
||||
<ResolveCurrentProjectStaticWebAssetsInputsDependsOn>$(ResolveCurrentProjectStaticWebAssetsInputsDependsOn);_AddGeneratedScopedCssFiles</ResolveCurrentProjectStaticWebAssetsInputsDependsOn>
|
||||
<GetCurrentProjectStaticWebAssetsDependsOn Condition="'$(UseBlazorWebAssembly)' == 'true'">$(GetCurrentProjectStaticWebAssetsDependsOn);IncludeScopedCssBundle;</GetCurrentProjectStaticWebAssetsDependsOn>
|
||||
<GetCurrentProjectStaticWebAssetsDependsOn Condition="'$(UsingMicrosoftNETSdkBlazorWebAssembly)' == 'true'">$(GetCurrentProjectStaticWebAssetsDependsOn);IncludeScopedCssBundle;</GetCurrentProjectStaticWebAssetsDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="ResolveScopedCssInputs">
|
||||
|
|
|
|||
|
|
@ -362,8 +362,6 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
|
||||
<Import Project="Microsoft.NET.Sdk.Razor.MvcApplicationPartsDiscovery.targets" Condition="'$(_TargetingNETCoreApp30OrLater)' == 'true'" />
|
||||
|
||||
<Import Project="Microsoft.NET.Sdk.Razor.Components.Wasm.targets" Condition="'$(_TargetingNET50OrLater)' == 'true' AND '$(UseBlazorWebAssembly)' == 'true'" />
|
||||
|
||||
<!--
|
||||
These are the targets that actually do compilation using CSC, separated from the main file for ease of maintenance.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,68 +0,0 @@
|
|||
// 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.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Tasks
|
||||
{
|
||||
public class BlazorReadSatelliteAssemblyFileTest
|
||||
{
|
||||
[Fact]
|
||||
public void WritesAndReadsRoundTrip()
|
||||
{
|
||||
// Arrange/Act
|
||||
var tempFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
|
||||
|
||||
var writer = new BlazorWriteSatelliteAssemblyFile
|
||||
{
|
||||
BuildEngine = Mock.Of<IBuildEngine>(),
|
||||
WriteFile = new TaskItem(tempFile),
|
||||
SatelliteAssembly = new[]
|
||||
{
|
||||
new TaskItem("Resources.fr.dll", new Dictionary<string, string>
|
||||
{
|
||||
["Culture"] = "fr",
|
||||
["DestinationSubDirectory"] = "fr\\",
|
||||
}),
|
||||
new TaskItem("Resources.ja-jp.dll", new Dictionary<string, string>
|
||||
{
|
||||
["Culture"] = "ja-jp",
|
||||
["DestinationSubDirectory"] = "ja-jp\\",
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
var reader = new BlazorReadSatelliteAssemblyFile
|
||||
{
|
||||
BuildEngine = Mock.Of<IBuildEngine>(),
|
||||
ReadFile = new TaskItem(tempFile),
|
||||
};
|
||||
|
||||
writer.Execute();
|
||||
|
||||
Assert.True(File.Exists(tempFile), "Write should have succeeded.");
|
||||
|
||||
reader.Execute();
|
||||
|
||||
Assert.Collection(
|
||||
reader.SatelliteAssembly,
|
||||
assembly =>
|
||||
{
|
||||
Assert.Equal("Resources.fr.dll", assembly.ItemSpec);
|
||||
Assert.Equal("fr", assembly.GetMetadata("Culture"));
|
||||
Assert.Equal("fr\\", assembly.GetMetadata("DestinationSubDirectory"));
|
||||
},
|
||||
assembly =>
|
||||
{
|
||||
Assert.Equal("Resources.ja-jp.dll", assembly.ItemSpec);
|
||||
Assert.Equal("ja-jp", assembly.GetMetadata("Culture"));
|
||||
Assert.Equal("ja-jp\\", assembly.GetMetadata("DestinationSubDirectory"));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,195 +0,0 @@
|
|||
// 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.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization.Json;
|
||||
using Microsoft.Build.Framework;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Tasks
|
||||
{
|
||||
public class GenerateBlazorWebAssemblyBootJsonTest
|
||||
{
|
||||
[Fact]
|
||||
public void GroupsResourcesByType()
|
||||
{
|
||||
// Arrange
|
||||
var taskInstance = new GenerateBlazorWebAssemblyBootJson
|
||||
{
|
||||
AssemblyPath = "MyApp.Entrypoint.dll",
|
||||
Resources = new[]
|
||||
{
|
||||
CreateResourceTaskItem(
|
||||
("FileName", "My.Assembly1"),
|
||||
("Extension", ".dll"),
|
||||
("FileHash", "abcdefghikjlmnopqrstuvwxyz")),
|
||||
|
||||
CreateResourceTaskItem(
|
||||
("FileName", "My.Assembly2"),
|
||||
("Extension", ".dll"),
|
||||
("FileHash", "012345678901234567890123456789")),
|
||||
|
||||
CreateResourceTaskItem(
|
||||
("FileName", "SomePdb"),
|
||||
("Extension", ".pdb"),
|
||||
("FileHash", "pdbhashpdbhashpdbhash")),
|
||||
|
||||
CreateResourceTaskItem(
|
||||
("FileName", "My.Assembly1"),
|
||||
("Extension", ".pdb"),
|
||||
("FileHash", "pdbdefghikjlmnopqrstuvwxyz")),
|
||||
|
||||
CreateResourceTaskItem(
|
||||
("FileName", "some-runtime-file"),
|
||||
("FileHash", "runtimehashruntimehash"),
|
||||
("AssetType", "native")),
|
||||
|
||||
CreateResourceTaskItem(
|
||||
("FileName", "satellite-assembly1"),
|
||||
("Extension", ".dll"),
|
||||
("FileHash", "hashsatelliteassembly1"),
|
||||
("Culture", "en-GB")),
|
||||
|
||||
CreateResourceTaskItem(
|
||||
("FileName", "satellite-assembly2"),
|
||||
("Extension", ".dll"),
|
||||
("FileHash", "hashsatelliteassembly2"),
|
||||
("Culture", "fr")),
|
||||
|
||||
CreateResourceTaskItem(
|
||||
("FileName", "satellite-assembly3"),
|
||||
("Extension", ".dll"),
|
||||
("FileHash", "hashsatelliteassembly3"),
|
||||
("Culture", "en-GB")),
|
||||
}
|
||||
};
|
||||
|
||||
using var stream = new MemoryStream();
|
||||
|
||||
// Act
|
||||
taskInstance.WriteBootJson(stream, "MyEntrypointAssembly");
|
||||
|
||||
// Assert
|
||||
var parsedContent = ParseBootData(stream);
|
||||
Assert.Equal("MyEntrypointAssembly", parsedContent.entryAssembly);
|
||||
|
||||
var resources = parsedContent.resources.assembly;
|
||||
Assert.Equal(2, resources.Count);
|
||||
Assert.Equal("sha256-abcdefghikjlmnopqrstuvwxyz", resources["My.Assembly1.dll"]);
|
||||
Assert.Equal("sha256-012345678901234567890123456789", resources["My.Assembly2.dll"]);
|
||||
|
||||
resources = parsedContent.resources.pdb;
|
||||
Assert.Equal(2, resources.Count);
|
||||
Assert.Equal("sha256-pdbhashpdbhashpdbhash", resources["SomePdb.pdb"]);
|
||||
Assert.Equal("sha256-pdbdefghikjlmnopqrstuvwxyz", resources["My.Assembly1.pdb"]);
|
||||
|
||||
resources = parsedContent.resources.runtime;
|
||||
Assert.Single(resources);
|
||||
Assert.Equal("sha256-runtimehashruntimehash", resources["some-runtime-file"]);
|
||||
|
||||
var satelliteResources = parsedContent.resources.satelliteResources;
|
||||
Assert.Collection(
|
||||
satelliteResources.OrderBy(kvp => kvp.Key),
|
||||
kvp =>
|
||||
{
|
||||
Assert.Equal("en-GB", kvp.Key);
|
||||
Assert.Collection(
|
||||
kvp.Value.OrderBy(item => item.Key),
|
||||
item =>
|
||||
{
|
||||
Assert.Equal("en-GB/satellite-assembly1.dll", item.Key);
|
||||
Assert.Equal("sha256-hashsatelliteassembly1", item.Value);
|
||||
},
|
||||
item =>
|
||||
{
|
||||
Assert.Equal("en-GB/satellite-assembly3.dll", item.Key);
|
||||
Assert.Equal("sha256-hashsatelliteassembly3", item.Value);
|
||||
});
|
||||
},
|
||||
kvp =>
|
||||
{
|
||||
Assert.Equal("fr", kvp.Key);
|
||||
Assert.Collection(
|
||||
kvp.Value.OrderBy(item => item.Key),
|
||||
item =>
|
||||
{
|
||||
Assert.Equal("fr/satellite-assembly2.dll", item.Key);
|
||||
Assert.Equal("sha256-hashsatelliteassembly2", item.Value);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false)]
|
||||
[InlineData(true)]
|
||||
public void CanSpecifyCacheBootResources(bool flagValue)
|
||||
{
|
||||
// Arrange
|
||||
var taskInstance = new GenerateBlazorWebAssemblyBootJson { CacheBootResources = flagValue };
|
||||
using var stream = new MemoryStream();
|
||||
|
||||
// Act
|
||||
taskInstance.WriteBootJson(stream, "MyEntrypointAssembly");
|
||||
|
||||
// Assert
|
||||
var parsedContent = ParseBootData(stream);
|
||||
Assert.Equal(flagValue, parsedContent.cacheBootResources);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false)]
|
||||
[InlineData(true)]
|
||||
public void CanSpecifyDebugBuild(bool flagValue)
|
||||
{
|
||||
// Arrange
|
||||
var taskInstance = new GenerateBlazorWebAssemblyBootJson { DebugBuild = flagValue };
|
||||
using var stream = new MemoryStream();
|
||||
|
||||
// Act
|
||||
taskInstance.WriteBootJson(stream, "MyEntrypointAssembly");
|
||||
|
||||
// Assert
|
||||
var parsedContent = ParseBootData(stream);
|
||||
Assert.Equal(flagValue, parsedContent.debugBuild);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false)]
|
||||
[InlineData(true)]
|
||||
public void CanSpecifyLinkerEnabled(bool flagValue)
|
||||
{
|
||||
// Arrange
|
||||
var taskInstance = new GenerateBlazorWebAssemblyBootJson { LinkerEnabled = flagValue };
|
||||
using var stream = new MemoryStream();
|
||||
|
||||
// Act
|
||||
taskInstance.WriteBootJson(stream, "MyEntrypointAssembly");
|
||||
|
||||
// Assert
|
||||
var parsedContent = ParseBootData(stream);
|
||||
Assert.Equal(flagValue, parsedContent.linkerEnabled);
|
||||
}
|
||||
|
||||
private static BootJsonData ParseBootData(Stream stream)
|
||||
{
|
||||
stream.Position = 0;
|
||||
var serializer = new DataContractJsonSerializer(
|
||||
typeof(BootJsonData),
|
||||
new DataContractJsonSerializerSettings { UseSimpleDictionaryFormat = true });
|
||||
return (BootJsonData)serializer.ReadObject(stream);
|
||||
}
|
||||
|
||||
private static ITaskItem CreateResourceTaskItem(params (string key, string value)[] values)
|
||||
{
|
||||
var mock = new Mock<ITaskItem>();
|
||||
|
||||
foreach (var (key, value) in values)
|
||||
{
|
||||
mock.Setup(m => m.GetMetadata(key)).Returns(value);
|
||||
}
|
||||
return mock.Object;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,9 +7,6 @@
|
|||
<ProjectReference Include="..\SimpleMvc21\SimpleMvc21.csproj" />
|
||||
<ProjectReference Include="..\SimpleMvc31\SimpleMvc31.csproj" />
|
||||
<ProjectReference Include="..\blazor31\blazor31.csproj" />
|
||||
<ProjectReference Include="..\blazorhosted\blazorhosted.csproj" />
|
||||
<ProjectReference Include="..\blazorhosted-rid\blazorhosted-rid.csproj" />
|
||||
<ProjectReference Include="..\blazorwasm\blazorwasm.csproj" />
|
||||
<ProjectReference Include="..\ClassLibraryMvc21\ClassLibraryMvc21.csproj" />
|
||||
<ProjectReference Include="..\AppWithP2PReference\AppWithP2PReference.csproj" />
|
||||
<ProjectReference Include="..\AppWithPackageAndP2PReferenceAndRID\AppWithPackageAndP2PReferenceAndRID.csproj" />
|
||||
|
|
|
|||
Loading…
Reference in New Issue