[Blazor][Wasm] Build fixes for incrementalism and PWA (#20861)
* Fixes incrementalism issue caused by a wrong up to date check * Fixes PWA template on hosted scenario by removing the 'ServiceWorker' from the content itemgroup in all scenarios.
This commit is contained in:
parent
4c312e1d51
commit
ad725861a9
|
|
@ -32,18 +32,16 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
|
|||
var inputSource = file.InputSource;
|
||||
var targetCompressionPath = file.Target;
|
||||
|
||||
if (!File.Exists(inputSource) ||
|
||||
(File.Exists(targetCompressionPath) && File.GetLastWriteTime(inputSource) > File.GetLastWriteTime(targetCompressionPath)))
|
||||
if (!File.Exists(inputSource))
|
||||
{
|
||||
Log.LogMessage($"Skipping '{inputPath}' because '{inputSource}' does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (File.Exists(targetCompressionPath) && File.GetLastWriteTimeUtc(inputSource) < File.GetLastWriteTimeUtc(targetCompressionPath))
|
||||
{
|
||||
// Incrementalism. If input source doesn't exist or it exists and is not newer than the expected output, do nothing.
|
||||
if (!File.Exists(inputSource))
|
||||
{
|
||||
Log.LogMessage($"Skipping '{inputPath}' because '{inputSource}' does not exist.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.LogMessage($"Skipping '{inputPath}' because '{inputSource}' is newer than '{targetCompressionPath}'.");
|
||||
}
|
||||
Log.LogMessage($"Skipping '{inputPath}' because '{targetCompressionPath}' is newer than '{inputSource}'.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -150,9 +150,9 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_ExistingBlazorOutputWithTargetPath Include="@(_BlazorOutputWithTargetPath)" Condition="Exists('%(FullPath)')" />
|
||||
<_ExistingBlazorOutputWithTargetPath Include="@(_BlazorOutputWithTargetPath)" Condition="Exists('%(FullPath)')" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<GetFileHash Files="@(_ExistingBlazorOutputWithTargetPath)" Algorithm="SHA256" HashEncoding="base64">
|
||||
<Output TaskParameter="Items" ItemName="_BlazorOutputWithHash" />
|
||||
</GetFileHash>
|
||||
|
|
@ -160,7 +160,7 @@
|
|||
<ItemGroup>
|
||||
<_BlazorOutputWithIntegrity Include="@(_BlazorOutputWithHash)">
|
||||
<Integrity>%(_BlazorOutputWithHash.FileHash)</Integrity>
|
||||
<IntegrityFile>$(IntermediateOutputPath)integrity\$([System.String]::Copy('%(FileHash)').Replace('/','-').Replace('+','_')).hash'</IntegrityFile>
|
||||
<IntegrityFile>$(IntermediateOutputPath)integrity\$([System.String]::Copy('%(FileHash)').Replace('/','-').Replace('+','_')).hash</IntegrityFile>
|
||||
</_BlazorOutputWithIntegrity>
|
||||
|
||||
<_BlazorOutputWithTargetPath Remove="@(_BlazorOutputWithIntegrity)" />
|
||||
|
|
@ -413,7 +413,7 @@
|
|||
|
||||
<_BlazorBootJsonWithIntegrity Include="@(_BlazorBootJsonWithHash)">
|
||||
<Integrity>%(FileHash)</Integrity>
|
||||
<IntegrityFile>$(IntermediateOutputPath)integrity\$([System.String]::Copy('%(FileHash)').Replace('/','-').Replace('+','_')).hash'</IntegrityFile>
|
||||
<IntegrityFile>$(IntermediateOutputPath)integrity\$([System.String]::Copy('%(FileHash)').Replace('/','-').Replace('+','_')).hash</IntegrityFile>
|
||||
</_BlazorBootJsonWithIntegrity>
|
||||
|
||||
<_BlazorOutputWithTargetPath Include="@(_BlazorBootJsonWithIntegrity)" RemoveMetadata="FileHash;FileHashAlgorithm">
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@
|
|||
<Target Name="_ComputeManifestIntegrity"
|
||||
Condition="'$(ServiceWorkerAssetsManifest)' != ''"
|
||||
BeforeTargets="_BlazorStaticWebAssetsCopyGeneratedFilesToOutputDirectory;_GzipCompressBlazorApplicationFiles">
|
||||
|
||||
|
||||
<GetFileHash Files="$(_ServiceWorkerAssetsManifestIntermediateOutputPath)" Algorithm="SHA256" HashEncoding="base64">
|
||||
<Output TaskParameter="Items" ItemName="_ServiceWorkerManifestWithHash" />
|
||||
</GetFileHash>
|
||||
|
|
@ -64,7 +64,7 @@
|
|||
|
||||
<_ServiceWorkerManifestWithIntegrity Include="@(_ServiceWorkerManifestWithHash)">
|
||||
<Integrity>%(FileHash)</Integrity>
|
||||
<IntegrityFile>$(IntermediateOutputPath)integrity\$([System.String]::Copy('%(FileHash)').Replace('/','-').Replace('+','_')).hash'</IntegrityFile>
|
||||
<IntegrityFile>$(IntermediateOutputPath)integrity\$([System.String]::Copy('%(FileHash)').Replace('/','-').Replace('+','_')).hash</IntegrityFile>
|
||||
</_ServiceWorkerManifestWithIntegrity>
|
||||
|
||||
<FileWrites Include="%(_ServiceWorkerManifestWithIntegrity.IntegrityFile)" />
|
||||
|
|
@ -74,7 +74,7 @@
|
|||
<WriteLinesToFile Lines="%(_ServiceWorkerManifestWithIntegrity.Integrity)" File="%(_ServiceWorkerManifestWithIntegrity.IntegrityFile)" WriteOnlyWhenDifferent="true" Overwrite="true" />
|
||||
|
||||
<PropertyGroup>
|
||||
<_ServiceWorkerManifestIntegrityFile>$(IntermediateOutputPath)integrity\$([System.String]::Copy('%(_ServiceWorkerManifestWithIntegrity.FileHash)').Replace('/','-').Replace('+','_')).hash'</_ServiceWorkerManifestIntegrityFile>
|
||||
<_ServiceWorkerManifestIntegrityFile>$(IntermediateOutputPath)integrity\$([System.String]::Copy('%(_ServiceWorkerManifestWithIntegrity.FileHash)').Replace('/','-').Replace('+','_')).hash</_ServiceWorkerManifestIntegrityFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
@ -178,7 +178,7 @@
|
|||
|
||||
<Target Name="_OmitServiceWorkerContent"
|
||||
Condition="'$(ServiceWorkerAssetsManifest)' != ''"
|
||||
BeforeTargets="AssignTargetPaths">
|
||||
BeforeTargets="AssignTargetPaths;ResolveCurrentProjectStaticWebAssets">
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Don't emit the service worker source files to the output -->
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// 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.Threading.Tasks;
|
||||
|
|
@ -40,6 +41,45 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Build_WithLinkerAndCompression_UpdatesFilesWhenSourcesChange()
|
||||
{
|
||||
// Arrange
|
||||
using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" });
|
||||
var result = await MSBuildProcessManager.DotnetMSBuild(project);
|
||||
|
||||
Assert.BuildPassed(result);
|
||||
|
||||
var mainAppDll = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll");
|
||||
var mainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll);
|
||||
var mainAppCompressedDll = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll.gz");
|
||||
var mainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll);
|
||||
|
||||
var blazorBootJson = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json");
|
||||
var blazorBootJsonThumbPrint = FileThumbPrint.Create(blazorBootJson);
|
||||
var blazorBootJsonCompressed = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json.gz");
|
||||
var blazorBootJsonCompressedThumbPrint = FileThumbPrint.Create(blazorBootJsonCompressed);
|
||||
|
||||
// Act
|
||||
var programFile = Path.Combine(project.DirectoryPath, "Program.cs");
|
||||
var programFileContents = File.ReadAllText(programFile);
|
||||
File.WriteAllText(programFile, programFileContents.Replace("args", "arguments"));
|
||||
result = await MSBuildProcessManager.DotnetMSBuild(project);
|
||||
|
||||
// Assert
|
||||
Assert.BuildPassed(result);
|
||||
var newMainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll);
|
||||
var newMainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll);
|
||||
var newBlazorBootJsonThumbPrint = FileThumbPrint.Create(blazorBootJson);
|
||||
var newBlazorBootJsonCompressedThumbPrint = FileThumbPrint.Create(blazorBootJsonCompressed);
|
||||
|
||||
Assert.NotEqual(mainAppDllThumbPrint, newMainAppDllThumbPrint);
|
||||
Assert.NotEqual(mainAppCompressedDllThumbPrint, newMainAppCompressedDllThumbPrint);
|
||||
|
||||
Assert.NotEqual(blazorBootJsonThumbPrint, newBlazorBootJsonThumbPrint);
|
||||
Assert.NotEqual(blazorBootJsonCompressedThumbPrint, newBlazorBootJsonCompressedThumbPrint);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Build_WithoutLinkerAndCompression_IsIncremental()
|
||||
{
|
||||
|
|
@ -70,6 +110,34 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Build_WithoutLinkerAndCompression_UpdatesFilesWhenSourcesChange()
|
||||
{
|
||||
// Arrange
|
||||
using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" });
|
||||
var result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/p:BlazorWebAssemblyEnableLinking=false");
|
||||
|
||||
// Act
|
||||
var mainAppDll = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll");
|
||||
var mainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll);
|
||||
|
||||
var mainAppCompressedDll = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll.gz");
|
||||
var mainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll);
|
||||
|
||||
var programFile = Path.Combine(project.DirectoryPath, "Program.cs");
|
||||
var programFileContents = File.ReadAllText(programFile);
|
||||
File.WriteAllText(programFile, programFileContents.Replace("args", "arguments"));
|
||||
|
||||
// Assert
|
||||
result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/p:BlazorWebAssemblyEnableLinking=false");
|
||||
Assert.BuildPassed(result);
|
||||
var newMainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll);
|
||||
var newMainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll);
|
||||
|
||||
Assert.NotEqual(mainAppDllThumbPrint, newMainAppDllThumbPrint);
|
||||
Assert.NotEqual(mainAppCompressedDllThumbPrint, newMainAppCompressedDllThumbPrint);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Build_CompressesAllFrameworkFiles()
|
||||
{
|
||||
|
|
@ -147,6 +215,77 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
|
|||
Assert.False(Directory.Exists(compressedFilesPath));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Publish_WithLinkerAndCompression_UpdatesFilesWhenSourcesChange()
|
||||
{
|
||||
// Arrange
|
||||
using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary" });
|
||||
project.TargetFramework = "netcoreapp3.1";
|
||||
var result = await MSBuildProcessManager.DotnetMSBuild(project, target: "publish");
|
||||
|
||||
Assert.BuildPassed(result);
|
||||
|
||||
// Act
|
||||
var mainAppDll = Path.Combine(project.DirectoryPath, project.PublishOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll");
|
||||
var mainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll);
|
||||
var mainAppCompressedDll = Path.Combine(project.DirectoryPath, project.PublishOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll.br");
|
||||
var mainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll);
|
||||
|
||||
var blazorBootJson = Path.Combine(project.DirectoryPath, project.PublishOutputDirectory, "wwwroot", "_framework", "blazor.boot.json");
|
||||
var blazorBootJsonThumbPrint = FileThumbPrint.Create(blazorBootJson);
|
||||
var blazorBootJsonCompressed = Path.Combine(project.DirectoryPath, project.PublishOutputDirectory, "wwwroot", "_framework", "blazor.boot.json.br");
|
||||
var blazorBootJsonCompressedThumbPrint = FileThumbPrint.Create(blazorBootJsonCompressed);
|
||||
|
||||
var programFile = Path.Combine(project.DirectoryPath, "..", "standalone", "Program.cs");
|
||||
var programFileContents = File.ReadAllText(programFile);
|
||||
File.WriteAllText(programFile, programFileContents.Replace("args", "arguments"));
|
||||
|
||||
// Assert
|
||||
result = await MSBuildProcessManager.DotnetMSBuild(project, target: "publish");
|
||||
Assert.BuildPassed(result);
|
||||
var newMainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll);
|
||||
var newMainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll);
|
||||
var newBlazorBootJsonThumbPrint = FileThumbPrint.Create(blazorBootJson);
|
||||
var newBlazorBootJsonCompressedThumbPrint = FileThumbPrint.Create(blazorBootJsonCompressed);
|
||||
|
||||
Assert.NotEqual(mainAppDllThumbPrint, newMainAppDllThumbPrint);
|
||||
Assert.NotEqual(mainAppCompressedDllThumbPrint, newMainAppCompressedDllThumbPrint);
|
||||
|
||||
Assert.NotEqual(blazorBootJsonThumbPrint, newBlazorBootJsonThumbPrint);
|
||||
Assert.NotEqual(blazorBootJsonCompressedThumbPrint, newBlazorBootJsonCompressedThumbPrint);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Publish_WithoutLinkerAndCompression_UpdatesFilesWhenSourcesChange()
|
||||
{
|
||||
// Arrange
|
||||
using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary" });
|
||||
project.TargetFramework = "netcoreapp3.1";
|
||||
var result = await MSBuildProcessManager.DotnetMSBuild(project, target: "publish", args: "/p:BlazorWebAssemblyEnableLinking=false");
|
||||
|
||||
Assert.BuildPassed(result);
|
||||
|
||||
// Act
|
||||
var mainAppDll = Path.Combine(project.DirectoryPath, project.PublishOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll");
|
||||
var mainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll);
|
||||
|
||||
var mainAppCompressedDll = Path.Combine(project.DirectoryPath, project.PublishOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll.br");
|
||||
var mainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll);
|
||||
|
||||
var programFile = Path.Combine(project.DirectoryPath, "..", "standalone", "Program.cs");
|
||||
var programFileContents = File.ReadAllText(programFile);
|
||||
File.WriteAllText(programFile, programFileContents.Replace("args", "arguments"));
|
||||
|
||||
// Assert
|
||||
result = await MSBuildProcessManager.DotnetMSBuild(project, target: "publish", args: "/p:BlazorWebAssemblyEnableLinking=false");
|
||||
Assert.BuildPassed(result);
|
||||
var newMainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll);
|
||||
var newMainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll);
|
||||
|
||||
Assert.NotEqual(mainAppDllThumbPrint, newMainAppDllThumbPrint);
|
||||
Assert.NotEqual(mainAppCompressedDllThumbPrint, newMainAppCompressedDllThumbPrint);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Publish_WithLinkerAndCompression_IsIncremental()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -35,18 +35,16 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build.BrotliCompression
|
|||
var inputSource = file.InputSource;
|
||||
var targetCompressionPath = file.Target;
|
||||
|
||||
if (!File.Exists(inputSource) ||
|
||||
(File.Exists(targetCompressionPath) && File.GetLastWriteTime(inputSource) > File.GetLastWriteTime(targetCompressionPath)))
|
||||
if (!File.Exists(inputSource))
|
||||
{
|
||||
Console.WriteLine($"Skipping '{inputPath}' because '{inputSource}' does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (File.Exists(targetCompressionPath) && File.GetLastWriteTimeUtc(inputSource) < File.GetLastWriteTimeUtc(targetCompressionPath))
|
||||
{
|
||||
// Incrementalism. If input source doesn't exist or it exists and is not newer than the expected output, do nothing.
|
||||
if (!File.Exists(inputSource))
|
||||
{
|
||||
Console.WriteLine($"Skipping '{inputPath}' because '{inputSource}' does not exist.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Skipping '{inputPath}' because '{inputSource}' is newer than '{targetCompressionPath}'.");
|
||||
}
|
||||
Console.WriteLine($"Skipping '{inputPath}' because '{targetCompressionPath}' is newer than '{inputSource}'.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue