diff --git a/src/Components/WebAssembly/Build/src/Tasks/GzipCompressBlazorApplicationFiles.cs b/src/Components/WebAssembly/Build/src/Tasks/GzipCompressBlazorApplicationFiles.cs
index 65aeb409f5..53d26328a3 100644
--- a/src/Components/WebAssembly/Build/src/Tasks/GzipCompressBlazorApplicationFiles.cs
+++ b/src/Components/WebAssembly/Build/src/Tasks/GzipCompressBlazorApplicationFiles.cs
@@ -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;
}
diff --git a/src/Components/WebAssembly/Build/src/targets/Blazor.MonoRuntime.targets b/src/Components/WebAssembly/Build/src/targets/Blazor.MonoRuntime.targets
index ebddf882f0..ddb7556f0b 100644
--- a/src/Components/WebAssembly/Build/src/targets/Blazor.MonoRuntime.targets
+++ b/src/Components/WebAssembly/Build/src/targets/Blazor.MonoRuntime.targets
@@ -150,9 +150,9 @@
- <_ExistingBlazorOutputWithTargetPath Include="@(_BlazorOutputWithTargetPath)" Condition="Exists('%(FullPath)')" />
+ <_ExistingBlazorOutputWithTargetPath Include="@(_BlazorOutputWithTargetPath)" Condition="Exists('%(FullPath)')" />
-
+
@@ -160,7 +160,7 @@
<_BlazorOutputWithIntegrity Include="@(_BlazorOutputWithHash)">
%(_BlazorOutputWithHash.FileHash)
- $(IntermediateOutputPath)integrity\$([System.String]::Copy('%(FileHash)').Replace('/','-').Replace('+','_')).hash'
+ $(IntermediateOutputPath)integrity\$([System.String]::Copy('%(FileHash)').Replace('/','-').Replace('+','_')).hash
<_BlazorOutputWithTargetPath Remove="@(_BlazorOutputWithIntegrity)" />
@@ -413,7 +413,7 @@
<_BlazorBootJsonWithIntegrity Include="@(_BlazorBootJsonWithHash)">
%(FileHash)
- $(IntermediateOutputPath)integrity\$([System.String]::Copy('%(FileHash)').Replace('/','-').Replace('+','_')).hash'
+ $(IntermediateOutputPath)integrity\$([System.String]::Copy('%(FileHash)').Replace('/','-').Replace('+','_')).hash
<_BlazorOutputWithTargetPath Include="@(_BlazorBootJsonWithIntegrity)" RemoveMetadata="FileHash;FileHashAlgorithm">
diff --git a/src/Components/WebAssembly/Build/src/targets/ServiceWorkerAssetsManifest.targets b/src/Components/WebAssembly/Build/src/targets/ServiceWorkerAssetsManifest.targets
index fcf1b38503..74654a8d33 100644
--- a/src/Components/WebAssembly/Build/src/targets/ServiceWorkerAssetsManifest.targets
+++ b/src/Components/WebAssembly/Build/src/targets/ServiceWorkerAssetsManifest.targets
@@ -55,7 +55,7 @@
-
+
@@ -64,7 +64,7 @@
<_ServiceWorkerManifestWithIntegrity Include="@(_ServiceWorkerManifestWithHash)">
%(FileHash)
- $(IntermediateOutputPath)integrity\$([System.String]::Copy('%(FileHash)').Replace('/','-').Replace('+','_')).hash'
+ $(IntermediateOutputPath)integrity\$([System.String]::Copy('%(FileHash)').Replace('/','-').Replace('+','_')).hash
@@ -74,7 +74,7 @@
- <_ServiceWorkerManifestIntegrityFile>$(IntermediateOutputPath)integrity\$([System.String]::Copy('%(_ServiceWorkerManifestWithIntegrity.FileHash)').Replace('/','-').Replace('+','_')).hash'
+ <_ServiceWorkerManifestIntegrityFile>$(IntermediateOutputPath)integrity\$([System.String]::Copy('%(_ServiceWorkerManifestWithIntegrity.FileHash)').Replace('/','-').Replace('+','_')).hash
@@ -178,7 +178,7 @@
+ BeforeTargets="AssignTargetPaths;ResolveCurrentProjectStaticWebAssets">
diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildCompressionTests.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildCompressionTests.cs
index 97f26ca308..476035b503 100644
--- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildCompressionTests.cs
+++ b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildCompressionTests.cs
@@ -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()
{
diff --git a/src/Components/WebAssembly/Compression/src/Program.cs b/src/Components/WebAssembly/Compression/src/Program.cs
index 093b2159ef..3391e96036 100644
--- a/src/Components/WebAssembly/Compression/src/Program.cs
+++ b/src/Components/WebAssembly/Compression/src/Program.cs
@@ -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;
}