[build] Disable gzip compression during build
This commit is contained in:
parent
1511692b1e
commit
ee9279bb5f
5 changed files with 60 additions and 121 deletions
|
@ -8,6 +8,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Import Project="..\Iceshrimp.Build\Iceshrimp.Build.props"/>
|
<Import Project="..\Iceshrimp.Build\Iceshrimp.Build.props"/>
|
||||||
|
<Import Project="..\Iceshrimp.Build\Iceshrimp.Build.targets"/>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Iceshrimp.Build\Iceshrimp.Build.csproj" PrivateAssets="all" IncludeAssets="build" />
|
<ProjectReference Include="..\Iceshrimp.Build\Iceshrimp.Build.csproj" PrivateAssets="all" IncludeAssets="build" />
|
||||||
|
@ -80,24 +81,4 @@
|
||||||
<None Remove="Core\Database\prune-designer-cs-files.sh" />
|
<None Remove="Core\Database\prune-designer-cs-files.sh" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<!-- This saves a bunch of disk space by discarding the original and gzip-compressed static assets. -->
|
|
||||||
<!-- For clients that don't support brotli, they will be transparently decompressed by the server. -->
|
|
||||||
<Target Name="KeepOnlyBrotliCompressedStaticAssets" AfterTargets="Publish">
|
|
||||||
<ItemGroup>
|
|
||||||
<CompressedFiles Include="$(PublishDir)\wwwroot\**\*.br" />
|
|
||||||
<FilesToClean Include="@(CompressedFiles->'%(RootDir)%(Directory)%(Filename)')" />
|
|
||||||
<FilesToClean Include="@(CompressedFiles->'%(RootDir)%(Directory)%(Filename).gz')" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<Delete Files="@(FilesToClean->Exists())" />
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<!-- This runs a task that rewrites the static asset endpoints JSON file to enable transparent decompression. -->
|
|
||||||
<ItemGroup>
|
|
||||||
<ManifestFiles Include="$(PublishDir)\Iceshrimp.Backend.staticwebassets.endpoints.json"/>
|
|
||||||
</ItemGroup>
|
|
||||||
<Target Name="RewriteStaticAssetManifest" AfterTargets="KeepOnlyBrotliCompressedStaticAssets">
|
|
||||||
<RewriteStaticAssetManifest ManifestFiles="@(ManifestFiles)" />
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -11,4 +11,9 @@
|
||||||
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.12.6" PrivateAssets="all" ExcludeAssets="Runtime" />
|
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.12.6" PrivateAssets="all" ExcludeAssets="Runtime" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="*.props" />
|
||||||
|
<None Remove="*.targets" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
41
Iceshrimp.Build/Iceshrimp.Build.targets
Normal file
41
Iceshrimp.Build/Iceshrimp.Build.targets
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
|
||||||
|
<!-- Disables static asset compression during regular builds -->
|
||||||
|
<Target Name="DisableBuildCompression" Condition="$(_IsPublishing)' != 'true'">
|
||||||
|
<PropertyGroup>
|
||||||
|
<DisableBuildCompression>true</DisableBuildCompression>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<!-- This saves a bunch of disk space by skipping gzip compression during publish. -->
|
||||||
|
<Target Name="OverrideBuildCompressionFormats" BeforeTargets="ResolveBuildCompressedStaticWebAssetsConfiguration">
|
||||||
|
<PropertyGroup>
|
||||||
|
<BuildCompressionFormats>;</BuildCompressionFormats>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<!-- This is also neeed to skip gzip compression during publish. -->
|
||||||
|
<Target Name="OverridePublishCompressionFormats" BeforeTargets="ResolvePublishCompressedStaticWebAssetsConfiguration">
|
||||||
|
<PropertyGroup>
|
||||||
|
<PublishCompressionFormats>;brotli</PublishCompressionFormats>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<!-- This saves a bunch of disk space by discarding uncompressed static assets. -->
|
||||||
|
<!-- For clients that don't support brotli, transparent stream decompression will be used. -->
|
||||||
|
<Target Name="KeepOnlyBrotliCompressedStaticAssets" AfterTargets="Publish">
|
||||||
|
<ItemGroup>
|
||||||
|
<CompressedFiles Include="$(PublishDir)\wwwroot\**\*.br" />
|
||||||
|
<FilesToClean Include="@(CompressedFiles->'%(RootDir)%(Directory)%(Filename)')" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Delete Files="@(FilesToClean->Exists())" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<!-- This rewrites the static asset endpoints JSON file to enable transparent decompression. -->
|
||||||
|
<Target Name="_RewriteStaticAssetManifest" AfterTargets="KeepOnlyBrotliCompressedStaticAssets">
|
||||||
|
<RewriteStaticAssetManifest Manifest="$(StaticWebAssetEndpointsBuildManifestPath)" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
</Project>
|
|
@ -1,5 +1,4 @@
|
||||||
using System.Diagnostics;
|
using System.Text.Json;
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using Microsoft.Build.Framework;
|
using Microsoft.Build.Framework;
|
||||||
|
|
||||||
|
@ -8,19 +7,14 @@ namespace Iceshrimp.Build.Tasks;
|
||||||
|
|
||||||
public class RewriteStaticAssetManifest : Microsoft.Build.Utilities.Task
|
public class RewriteStaticAssetManifest : Microsoft.Build.Utilities.Task
|
||||||
{
|
{
|
||||||
public static void FixupFile(string manifestPath)
|
|
||||||
{
|
|
||||||
var parsed = Parse(manifestPath);
|
|
||||||
var @fixed = Fixup(manifestPath, parsed);
|
|
||||||
Write(manifestPath, @fixed);
|
|
||||||
}
|
|
||||||
|
|
||||||
[System.ComponentModel.DataAnnotations.Required]
|
[System.ComponentModel.DataAnnotations.Required]
|
||||||
public required ITaskItem[] ManifestFiles { get; set; }
|
public required ITaskItem Manifest { get; set; }
|
||||||
|
|
||||||
public override bool Execute()
|
public override bool Execute()
|
||||||
{
|
{
|
||||||
foreach (var item in ManifestFiles) FixupFile(item.ItemSpec);
|
var parsed = Parse(Manifest.ItemSpec);
|
||||||
|
var @fixed = Fixup(Manifest.ItemSpec, parsed);
|
||||||
|
Write(Manifest.ItemSpec, @fixed);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,15 +48,6 @@ public class RewriteStaticAssetManifest : Microsoft.Build.Utilities.Task
|
||||||
p => p.ResponseHeaders
|
p => p.ResponseHeaders
|
||||||
.FirstOrDefault(i => i.Name == "Content-Length"));
|
.FirstOrDefault(i => i.Name == "Content-Length"));
|
||||||
|
|
||||||
// Remove gzip-compressed versions
|
|
||||||
foreach (var endpoint in manifest.Endpoints.ToArray())
|
|
||||||
{
|
|
||||||
if (!endpoint.Selectors.Any(p => p is { Name: "Content-Encoding", Value: "gzip" }))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
manifest.Endpoints.Remove(endpoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rewrite uncompressed versions to reference brotli-compressed asset instead
|
// Rewrite uncompressed versions to reference brotli-compressed asset instead
|
||||||
foreach (var endpoint in manifest.Endpoints.ToArray())
|
foreach (var endpoint in manifest.Endpoints.ToArray())
|
||||||
{
|
{
|
||||||
|
@ -93,15 +78,9 @@ public class RewriteStaticAssetManifest : Microsoft.Build.Utilities.Task
|
||||||
|
|
||||||
// ReSharper disable once CollectionNeverUpdated.Local
|
// ReSharper disable once CollectionNeverUpdated.Local
|
||||||
public List<StaticAssetDescriptor> Endpoints { get; set; } = [];
|
public List<StaticAssetDescriptor> Endpoints { get; set; } = [];
|
||||||
|
|
||||||
public bool IsBuildManifest() => string.Equals(ManifestType, "Build", StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private sealed class StaticAssetDescriptor
|
||||||
/// The description of a static asset that was generated during the build process.
|
|
||||||
/// </summary>
|
|
||||||
[DebuggerDisplay($"{{{nameof(GetDebuggerDisplay)}(),nq}}")]
|
|
||||||
public sealed class StaticAssetDescriptor
|
|
||||||
{
|
{
|
||||||
private string? _route;
|
private string? _route;
|
||||||
private string? _assetFile;
|
private string? _assetFile;
|
||||||
|
@ -109,18 +88,12 @@ public class RewriteStaticAssetManifest : Microsoft.Build.Utilities.Task
|
||||||
private List<StaticAssetProperty> _endpointProperties = [];
|
private List<StaticAssetProperty> _endpointProperties = [];
|
||||||
private List<StaticAssetResponseHeader> _responseHeaders = [];
|
private List<StaticAssetResponseHeader> _responseHeaders = [];
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The route that the asset is served from.
|
|
||||||
/// </summary>
|
|
||||||
public required string Route
|
public required string Route
|
||||||
{
|
{
|
||||||
get => _route ?? throw new InvalidOperationException("Route is required");
|
get => _route ?? throw new InvalidOperationException("Route is required");
|
||||||
set => _route = value;
|
set => _route = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The path to the asset file from the wwwroot folder.
|
|
||||||
/// </summary>
|
|
||||||
[JsonPropertyName("AssetFile")]
|
[JsonPropertyName("AssetFile")]
|
||||||
public required string AssetPath
|
public required string AssetPath
|
||||||
{
|
{
|
||||||
|
@ -128,9 +101,6 @@ public class RewriteStaticAssetManifest : Microsoft.Build.Utilities.Task
|
||||||
set => _assetFile = value;
|
set => _assetFile = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A list of selectors that are used to discriminate between two or more assets with the same route.
|
|
||||||
/// </summary>
|
|
||||||
[JsonPropertyName("Selectors")]
|
[JsonPropertyName("Selectors")]
|
||||||
public List<StaticAssetSelector> Selectors
|
public List<StaticAssetSelector> Selectors
|
||||||
{
|
{
|
||||||
|
@ -138,9 +108,6 @@ public class RewriteStaticAssetManifest : Microsoft.Build.Utilities.Task
|
||||||
set => _selectors = value;
|
set => _selectors = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A list of properties that are associated with the endpoint.
|
|
||||||
/// </summary>
|
|
||||||
[JsonPropertyName("EndpointProperties")]
|
[JsonPropertyName("EndpointProperties")]
|
||||||
public List<StaticAssetProperty> Properties
|
public List<StaticAssetProperty> Properties
|
||||||
{
|
{
|
||||||
|
@ -148,87 +115,29 @@ public class RewriteStaticAssetManifest : Microsoft.Build.Utilities.Task
|
||||||
set => _endpointProperties = value;
|
set => _endpointProperties = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A list of headers to apply to the response when this resource is served.
|
|
||||||
/// </summary>
|
|
||||||
[JsonPropertyName("ResponseHeaders")]
|
[JsonPropertyName("ResponseHeaders")]
|
||||||
public List<StaticAssetResponseHeader> ResponseHeaders
|
public List<StaticAssetResponseHeader> ResponseHeaders
|
||||||
{
|
{
|
||||||
get => _responseHeaders;
|
get => _responseHeaders;
|
||||||
set => _responseHeaders = value;
|
set => _responseHeaders = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetDebuggerDisplay()
|
|
||||||
{
|
|
||||||
return $"Route: {Route} Path: {AssetPath}";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private sealed class StaticAssetSelector(string name, string value)
|
||||||
/// A static asset selector. Selectors are used to discriminate between two or more assets with the same route.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="name">The name associated to the selector.</param>
|
|
||||||
/// <param name="value">The value associated to the selector and used to match against incoming requests.</param>
|
|
||||||
/// <param name="quality">The static server quality associated to this selector.</param>
|
|
||||||
[DebuggerDisplay($"{{{nameof(GetDebuggerDisplay)}(),nq}}")]
|
|
||||||
public sealed class StaticAssetSelector(string name, string value, string quality)
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The name associated to the selector.
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The value associated to the selector and used to match against incoming requests.
|
|
||||||
/// </summary>
|
|
||||||
public string Value { get; } = value;
|
public string Value { get; } = value;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The static asset server quality associated to this selector. Used to break ties when a request matches multiple values
|
|
||||||
/// with the same degree of specificity.
|
|
||||||
/// </summary>
|
|
||||||
public string Quality { get; } = quality;
|
|
||||||
|
|
||||||
private string GetDebuggerDisplay() => $"Name: {Name} Value: {Value} Quality: {Quality}";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private sealed class StaticAssetProperty(string name, string value)
|
||||||
/// A property associated with a static asset.
|
|
||||||
/// </summary>
|
|
||||||
[DebuggerDisplay($"{{{nameof(GetDebuggerDisplay)}(),nq}}")]
|
|
||||||
public sealed class StaticAssetProperty(string name, string value)
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The name of the property.
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The value of the property.
|
|
||||||
/// </summary>
|
|
||||||
public string Value { get; } = value;
|
public string Value { get; } = value;
|
||||||
|
|
||||||
private string GetDebuggerDisplay() => $"Name: {Name} Value:{Value}";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private sealed class StaticAssetResponseHeader(string name, string value)
|
||||||
/// A response header to apply to the response when a static asset is served.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="name">The name of the header.</param>
|
|
||||||
/// <param name="value">The value of the header.</param>
|
|
||||||
[DebuggerDisplay($"{{{nameof(GetDebuggerDisplay)}(),nq}}")]
|
|
||||||
public sealed class StaticAssetResponseHeader(string name, string value)
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The name of the header.
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The value of the header.
|
|
||||||
/// </summary>
|
|
||||||
public string Value { get; } = value;
|
public string Value { get; } = value;
|
||||||
|
|
||||||
private string GetDebuggerDisplay() => $"Name: {Name} Value: {Value}";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,6 +6,9 @@
|
||||||
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
|
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Import Project="..\Iceshrimp.Build\Iceshrimp.Build.props"/>
|
||||||
|
<Import Project="..\Iceshrimp.Build\Iceshrimp.Build.targets"/>
|
||||||
|
|
||||||
<!-- Disables erroneous ILLink warnings. See https://github.com/dotnet/fsharp/issues/15261#issuecomment-1562959640 for more details.-->
|
<!-- Disables erroneous ILLink warnings. See https://github.com/dotnet/fsharp/issues/15261#issuecomment-1562959640 for more details.-->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<NoWarn>IL2008,IL2040</NoWarn>
|
<NoWarn>IL2008,IL2040</NoWarn>
|
||||||
|
|
Loading…
Add table
Reference in a new issue