Use StaticWebAssetBasePath if specified to calculate blazorwasm publish paths (#27896)
In 3.2, Blazor WebAssembly had a feature which allowed prefix the relative path within the PublishDir by configuring a StaticWebAssetBasePath property in the project file. As part of migrating to 5.0, this feature was (accidentally) not brought forward which is remedied by this commit. * Use StaticWebAssetBasePath to calculate asset base paths * Add publish tests to verify hosted and standalone scenarios Fixes https://github.com/dotnet/aspnetcore/issues/27776 Co-authored-by: Artak <34246760+mkArtakMSFT@users.noreply.github.com>
This commit is contained in:
parent
26c2891c60
commit
d9dd46ec8e
|
|
@ -12,11 +12,16 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
{
|
{
|
||||||
internal static class ServiceWorkerAssert
|
internal static class ServiceWorkerAssert
|
||||||
{
|
{
|
||||||
internal static void VerifyServiceWorkerFiles(MSBuildResult result, string outputDirectory, string serviceWorkerPath, string serviceWorkerContent, string assetsManifestPath)
|
internal static void VerifyServiceWorkerFiles(MSBuildResult result,
|
||||||
|
string outputDirectory,
|
||||||
|
string serviceWorkerPath,
|
||||||
|
string serviceWorkerContent,
|
||||||
|
string assetsManifestPath,
|
||||||
|
string staticWebAssetsBasePath = "")
|
||||||
{
|
{
|
||||||
// Check the expected files are there
|
// Check the expected files are there
|
||||||
var serviceWorkerResolvedPath = Assert.FileExists(result, outputDirectory, serviceWorkerPath);
|
var serviceWorkerResolvedPath = Assert.FileExists(result, outputDirectory, staticWebAssetsBasePath, serviceWorkerPath);
|
||||||
var assetsManifestResolvedPath = Assert.FileExists(result, outputDirectory, assetsManifestPath);
|
var assetsManifestResolvedPath = Assert.FileExists(result, outputDirectory, staticWebAssetsBasePath, assetsManifestPath);
|
||||||
|
|
||||||
// Check the service worker contains the expected content (which comes from the PublishedContent file)
|
// Check the service worker contains the expected content (which comes from the PublishedContent file)
|
||||||
Assert.FileContains(result, serviceWorkerResolvedPath, serviceWorkerContent);
|
Assert.FileContains(result, serviceWorkerResolvedPath, serviceWorkerContent);
|
||||||
|
|
@ -36,8 +41,8 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
// We don't list compressed files in the SWAM, as these are transparent to the client,
|
// We don't list compressed files in the SWAM, as these are transparent to the client,
|
||||||
// nor do we list the service worker itself or its assets manifest, as these don't need to be fetched in the same way
|
// nor do we list the service worker itself or its assets manifest, as these don't need to be fetched in the same way
|
||||||
if (IsCompressedFile(relativePath)
|
if (IsCompressedFile(relativePath)
|
||||||
|| string.Equals(relativePath, serviceWorkerPath, StringComparison.Ordinal)
|
|| string.Equals(relativePath, Path.Combine(staticWebAssetsBasePath, serviceWorkerPath), StringComparison.Ordinal)
|
||||||
|| string.Equals(relativePath, assetsManifestPath, StringComparison.Ordinal))
|
|| string.Equals(relativePath, Path.Combine(staticWebAssetsBasePath, assetsManifestPath), StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -252,6 +252,111 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
VerifyCompression(result, blazorPublishDirectory);
|
VerifyCompression(result, blazorPublishDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Publish_WithStaticWebBasePathWorks()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
using var project = ProjectDirectory.Create("blazorwasm", "razorclasslibrary");
|
||||||
|
project.AddProjectFileContent(
|
||||||
|
@"<PropertyGroup>
|
||||||
|
<StaticWebAssetBasePath>different-path/</StaticWebAssetBasePath>
|
||||||
|
</PropertyGroup>");
|
||||||
|
var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish");
|
||||||
|
|
||||||
|
Assert.BuildPassed(result);
|
||||||
|
|
||||||
|
var publishDirectory = project.PublishOutputDirectory;
|
||||||
|
|
||||||
|
// Verify nothing is published directly to the wwwroot directory
|
||||||
|
Assert.FileCountEquals(result, 0, Path.Combine(publishDirectory, "wwwroot"), "*", SearchOption.TopDirectoryOnly);
|
||||||
|
|
||||||
|
var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot", "different-path");
|
||||||
|
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json");
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js");
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_framework", "dotnet.wasm");
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_framework", DotNetJsFileName);
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazorwasm.dll");
|
||||||
|
|
||||||
|
// Verify static assets are in the publish directory
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "index.html");
|
||||||
|
|
||||||
|
// Verify web.config
|
||||||
|
Assert.FileExists(result, publishDirectory, "web.config");
|
||||||
|
var webConfigContent = new StreamReader(GetType().Assembly.GetManifestResourceStream("Microsoft.NET.Sdk.BlazorWebAssembly.IntegrationTests.BlazorWasm.web.config")).ReadToEnd();
|
||||||
|
Assert.FileContentEquals(result, Path.Combine(publishDirectory, "web.config"), webConfigContent);
|
||||||
|
Assert.FileCountEquals(result, 1, publishDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
|
|
||||||
|
// Verify static web assets from referenced projects are copied.
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js");
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "styles.css");
|
||||||
|
|
||||||
|
VerifyBootManifestHashes(result, blazorPublishDirectory);
|
||||||
|
VerifyServiceWorkerFiles(result,
|
||||||
|
Path.Combine(publishDirectory, "wwwroot"),
|
||||||
|
serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"),
|
||||||
|
serviceWorkerContent: "// This is the production service worker",
|
||||||
|
assetsManifestPath: "custom-service-worker-assets.js",
|
||||||
|
staticWebAssetsBasePath: "different-path");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Publish_Hosted_WithStaticWebBasePathWorks()
|
||||||
|
{
|
||||||
|
using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "blazorwasm", "razorclasslibrary", });
|
||||||
|
var wasmProject = project.GetSibling("blazorwasm");
|
||||||
|
wasmProject.AddProjectFileContent(
|
||||||
|
@"<PropertyGroup>
|
||||||
|
<StaticWebAssetBasePath>different-path/</StaticWebAssetBasePath>
|
||||||
|
</PropertyGroup>");
|
||||||
|
var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish");
|
||||||
|
|
||||||
|
Assert.BuildPassed(result);
|
||||||
|
|
||||||
|
var publishDirectory = project.PublishOutputDirectory;
|
||||||
|
// Make sure the main project exists
|
||||||
|
Assert.FileExists(result, publishDirectory, "blazorhosted.dll");
|
||||||
|
|
||||||
|
Assert.FileExists(result, publishDirectory, "RazorClassLibrary.dll");
|
||||||
|
Assert.FileExists(result, publishDirectory, "blazorwasm.dll");
|
||||||
|
|
||||||
|
var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot", "different-path");
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json");
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js");
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_framework", "dotnet.wasm");
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_framework", DotNetJsFileName);
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazorwasm.dll");
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_framework", "System.Text.Json.dll"); // Verify dependencies are part of the output.
|
||||||
|
|
||||||
|
// Verify project references appear as static web assets
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_framework", "RazorClassLibrary.dll");
|
||||||
|
// Also verify project references to the server project appear in the publish output
|
||||||
|
Assert.FileExists(result, publishDirectory, "RazorClassLibrary.dll");
|
||||||
|
|
||||||
|
// Verify static assets are in the publish directory
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "index.html");
|
||||||
|
|
||||||
|
// Verify static web assets from referenced projects are copied.
|
||||||
|
Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js");
|
||||||
|
Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "styles.css");
|
||||||
|
|
||||||
|
// Verify web.config
|
||||||
|
Assert.FileExists(result, publishDirectory, "web.config");
|
||||||
|
|
||||||
|
VerifyBootManifestHashes(result, blazorPublishDirectory);
|
||||||
|
|
||||||
|
// Verify compression works
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_framework", "dotnet.wasm.br");
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazorwasm.dll.br");
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_framework", "RazorClassLibrary.dll.br");
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_framework", "System.Text.Json.dll.br");
|
||||||
|
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_framework", "dotnet.wasm.gz");
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazorwasm.dll.gz");
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_framework", "RazorClassLibrary.dll.gz");
|
||||||
|
Assert.FileExists(result, blazorPublishDirectory, "_framework", "System.Text.Json.dll.gz");
|
||||||
|
}
|
||||||
|
|
||||||
private static void VerifyCompression(MSBuildResult result, string blazorPublishDirectory)
|
private static void VerifyCompression(MSBuildResult result, string blazorPublishDirectory)
|
||||||
{
|
{
|
||||||
var original = Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json");
|
var original = Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json");
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,6 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
|
||||||
<!-- Internal properties -->
|
<!-- Internal properties -->
|
||||||
<_BlazorOutputPath>wwwroot\_framework\</_BlazorOutputPath>
|
<_BlazorOutputPath>wwwroot\_framework\</_BlazorOutputPath>
|
||||||
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
@ -457,6 +456,12 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
<Output TaskParameter="JoinResult" ItemName="_ResolvedSatelliteToPublish" />
|
<Output TaskParameter="JoinResult" ItemName="_ResolvedSatelliteToPublish" />
|
||||||
</JoinItems>
|
</JoinItems>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<_BlazorPublishOutputPath Condition="'$(StaticWebAssetBasePath)' != '/'">wwwroot\$(StaticWebAssetBasePath.Replace('/', '\'))</_BlazorPublishOutputPath>
|
||||||
|
<_BlazorPublishOutputPath Condition="'$(StaticWebAssetBasePath)' == '/'">wwwroot\</_BlazorPublishOutputPath>
|
||||||
|
<_BlazorFrameworkPublishPath>$(_BlazorPublishOutputPath)_framework\</_BlazorFrameworkPublishPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResolvedFileToPublish Remove="@(_ResolvedSatelliteToPublish)" />
|
<ResolvedFileToPublish Remove="@(_ResolvedSatelliteToPublish)" />
|
||||||
<ResolvedFileToPublish Include="@(_ResolvedSatelliteToPublish)" />
|
<ResolvedFileToPublish Include="@(_ResolvedSatelliteToPublish)" />
|
||||||
|
|
@ -472,13 +477,24 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
<!-- Remove dotnet.js from publish output -->
|
<!-- Remove dotnet.js from publish output -->
|
||||||
<ResolvedFileToPublish Remove="@(ResolvedFileToPublish)" Condition="'%(ResolvedFileToPublish.RelativePath)' == 'dotnet.js'" />
|
<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 -->
|
<!-- Remove pdbs from the publish output -->
|
||||||
<ResolvedFileToPublish Remove="@(ResolvedFileToPublish)" Condition="'$(CopyOutputSymbolsToPublishDirectory)' != 'true' AND '%(Extension)' == '.pdb'" />
|
<ResolvedFileToPublish Remove="@(ResolvedFileToPublish)" Condition="'$(CopyOutputSymbolsToPublishDirectory)' != 'true' AND '%(Extension)' == '.pdb'" />
|
||||||
|
|
||||||
|
<!-- Retarget so that items are published to the wwwroot directory -->
|
||||||
|
<!--
|
||||||
|
This changes files (such as wwwroot/index.html) that are published to $(PublishDir)wwwroot\ -> $(PublishDir)wwwroot\$(StaticWebAssetBasePath)\.
|
||||||
|
Ignore any user specified web.config in the process.
|
||||||
|
-->
|
||||||
|
<ResolvedFileToPublish
|
||||||
|
RelativePath="$(_BlazorPublishOutputPath)$([System.String]::Copy('%(ResolvedFileToPublish.RelativePath)').Replace('/','\').Substring(8))"
|
||||||
|
Condition="'$(StaticWebAssetBasePath)' != '/' AND $([System.String]::Copy('%(ResolvedFileToPublish.RelativePath)').Replace('/','\').StartsWith('wwwroot\'))" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Change all remaining publish output to publish to appear under the $(PublishDir)wwwroot\$(StaticWebAssetBasePath) path.
|
||||||
|
-->
|
||||||
|
<ResolvedFileToPublish
|
||||||
|
RelativePath="$(_BlazorFrameworkPublishPath)%(ResolvedFileToPublish.RelativePath)"
|
||||||
|
Condition="'%(ResolvedFileToPublish.RelativePath)' != 'web.config' AND !$([System.String]::Copy('%(ResolvedFileToPublish.RelativePath)').Replace('/','\').StartsWith('wwwroot\'))" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition="'@(ResolvedFileToPublish->AnyHaveMetadataValue('RelativePath', 'web.config'))' != 'true'">
|
<ItemGroup Condition="'@(ResolvedFileToPublish->AnyHaveMetadataValue('RelativePath', 'web.config'))' != 'true'">
|
||||||
|
|
@ -515,11 +531,11 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResolvedFileToPublish
|
<ResolvedFileToPublish
|
||||||
Include="$(IntermediateOutputPath)blazor.publish.boot.json"
|
Include="$(IntermediateOutputPath)blazor.publish.boot.json"
|
||||||
RelativePath="$(_BlazorOutputPath)blazor.boot.json" />
|
RelativePath="$(_BlazorFrameworkPublishPath)blazor.boot.json" />
|
||||||
|
|
||||||
<ResolvedFileToPublish
|
<ResolvedFileToPublish
|
||||||
Include="@(_BlazorJSFile)"
|
Include="@(_BlazorJSFile)"
|
||||||
RelativePath="$(_BlazorOutputPath)%(FileName)%(Extension)" />
|
RelativePath="$(_BlazorFrameworkPublishPath)%(FileName)%(Extension)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
<ContentSourcePath Condition="'%(ServiceWorker.PublishedContent)' != ''">%(ServiceWorker.PublishedContent)</ContentSourcePath>
|
<ContentSourcePath Condition="'%(ServiceWorker.PublishedContent)' != ''">%(ServiceWorker.PublishedContent)</ContentSourcePath>
|
||||||
<ContentSourcePath Condition="'%(ServiceWorker.PublishedContent)' == ''">%(ServiceWorker.Identity)</ContentSourcePath>
|
<ContentSourcePath Condition="'%(ServiceWorker.PublishedContent)' == ''">%(ServiceWorker.Identity)</ContentSourcePath>
|
||||||
<RelativePath>%(ServiceWorker.Identity)</RelativePath>
|
<RelativePath>%(ServiceWorker.Identity)</RelativePath>
|
||||||
|
<RelativePath Condition="$([System.String]::Copy('%(ServiceWorker.Identity)').Replace('/','\').StartsWith('wwwroot\'))">$(_BlazorPublishOutputPath)$([System.String]::Copy('%(ServiceWorker.Identity)').Substring(8))</RelativePath>
|
||||||
</_ServiceWorkerIntermediatePublishFile>
|
</_ServiceWorkerIntermediatePublishFile>
|
||||||
|
|
||||||
<_ServiceWorkerPublishFile Include="@(ResolvedFileToPublish)" Condition="$([System.String]::Copy('%(ResolvedFileToPublish.RelativePath)').Replace('\','/').StartsWith('wwwroot/'))">
|
<_ServiceWorkerPublishFile Include="@(ResolvedFileToPublish)" Condition="$([System.String]::Copy('%(ResolvedFileToPublish.RelativePath)').Replace('\','/').StartsWith('wwwroot/'))">
|
||||||
|
|
@ -161,7 +162,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
<ResolvedFileToPublish
|
<ResolvedFileToPublish
|
||||||
Include="$(_ServiceWorkerAssetsManifestPublishIntermediateOutputPath)"
|
Include="$(_ServiceWorkerAssetsManifestPublishIntermediateOutputPath)"
|
||||||
CopyToPublishDirectory="PreserveNewest"
|
CopyToPublishDirectory="PreserveNewest"
|
||||||
RelativePath="wwwroot\$(ServiceWorkerAssetsManifest)"
|
RelativePath="$(_BlazorPublishOutputPath)$(ServiceWorkerAssetsManifest)"
|
||||||
ExcludeFromSingleFile="true" />
|
ExcludeFromSingleFile="true" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Target>
|
</Target>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue