Skip to content

Latest commit

 

History

History
325 lines (246 loc) · 9.86 KB

File metadata and controls

325 lines (246 loc) · 9.86 KB

DotnetDevKR.TailwindCSS Package Improvement Specifications

Generated based on analysis of AspNetCore.SassCompiler, BundlerMinifier, WebCompiler, and Microsoft NuGet best practices.

Executive Summary

This document outlines improvements to elevate DotnetDevKR.TailwindCSS to production-quality standards based on industry best practices and comparable NuGet packages.


Phase 1: Critical Package Metadata (Priority: HIGH)

1.1 Add Package Icon

Status: MISSING Impact: Package appears incomplete on NuGet.org, reduced discoverability

Requirements:

  • Create 128x128 PNG icon with transparent background
  • Embed in package (not external URL)
  • Add to root of repository as icon.png

Implementation:

<PackageIcon>icon.png</PackageIcon>
<ItemGroup>
  <None Include="..\icon.png" Pack="true" PackagePath="\" />
</ItemGroup>

1.2 Add Package Description

Status: MISSING Impact: NuGet.org shows blank description

Recommended:

<Description>Automatic TailwindCSS compilation for .NET projects without Node.js dependency. Includes cross-platform standalone CLI with MSBuild integration supporting Blazor, ASP.NET Core, and Razor projects.</Description>

1.3 Expand Package Tags

Current: <PackageTags>TailwindCSS</PackageTags> Impact: Poor search discoverability

Recommended:

<PackageTags>tailwindcss;tailwind;css;msbuild;aspnetcore;blazor;compiler;build;frontend;no-nodejs;standalone</PackageTags>

1.4 Add Missing Metadata Properties

<PackageProjectUrl>https://github.com/dotnetdev-kr/DotnetDevKR.TailwindCSS</PackageProjectUrl>
<Copyright>Copyright (c) 2024-2025 DotnetDevKR</Copyright>
<PackageReleaseNotes>See https://github.com/dotnetdev-kr/DotnetDevKR.TailwindCSS/releases</PackageReleaseNotes>
<DevelopmentDependency>true</DevelopmentDependency>

Phase 2: MSBuild Integration Improvements (Priority: HIGH)

2.1 Add Conditional Execution

Status: MISSING Pattern from: BundlerMinifier

Users should be able to disable TailwindCSS compilation:

<Target Name="RunTailwindCSSTask"
        BeforeTargets="Build"
        Condition="'$(RunTailwindCSS)' != 'false' AND '$(DesignTimeBuild)' != 'true'"
        Inputs="@(Watch);$(InputFilename)"
        Outputs="$(OutputFilename)">

2.2 Add Property Defaults

Status: MISSING Impact: Build fails silently if user forgets configuration

<PropertyGroup>
  <InputFilename Condition="'$(InputFilename)' == ''">$(ProjectDir)tailwind.css</InputFilename>
  <IsMinify Condition="'$(IsMinify)' == ''">false</IsMinify>
  <DebugMode Condition="'$(DebugMode)' == ''">false</DebugMode>
</PropertyGroup>

2.3 Improve Watch Patterns

Current: Watches **\*.cs, **\*.cshtml, **\*.html, **\*.razor Issue: C# changes trigger unnecessary recompilation

Recommended:

<ItemGroup>
  <Watch Include="**\*.razor" AlwaysRebuild="true" />
  <Watch Include="**\*.html" AlwaysRebuild="true" />
  <Watch Include="**\*.cshtml" AlwaysRebuild="true" />
  <Watch Include="tailwind.config.js" AlwaysRebuild="true" Condition="Exists('$(ProjectDir)tailwind.config.js')" />
  <Watch Include="**\*.css" Exclude="$(OutputFilename)" AlwaysRebuild="true" />
</ItemGroup>

Remove **\*.cs from watch list.


Phase 3: Error Handling & Validation (Priority: HIGH)

3.1 Add Input Validation in TailwindCSSTask

Current: No validation Impact: Silent failures, confusing error messages

public override bool Execute()
{
    if (string.IsNullOrEmpty(OutputFilename))
    {
        Log.LogError("TAILWIND001: OutputFilename property is required. Add <OutputFilename> to your project configuration.");
        return false;
    }

    if (!string.IsNullOrEmpty(InputFilename) && !File.Exists(InputFilename))
    {
        Log.LogWarning("TAILWIND002: Input file not found: {0}. TailwindCSS will scan for utility classes only.", InputFilename);
    }

    // Change from LogWarning to LogMessage
    Log.LogMessage(MessageImportance.High, $"Compiling TailwindCSS from '{InputFilename ?? "(auto)"}' to '{OutputFilename}'");

    // ... rest
}

3.2 Improve Exception Handling in Compiler

Current: Generic exceptions, no timeout Impact: Hung builds, poor error messages

public async Task CompileAsync(...)
{
    using var process = CreateTailwindCSSProcess(...);

    using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(5));

    try
    {
        process.Start();
        // ... existing stream handling
        await process.WaitForExitAsync(cts.Token);
    }
    catch (OperationCanceledException)
    {
        process.Kill(entireProcessTree: true);
        throw new TailwindCSSCompilationException("TailwindCSS compilation timed out after 5 minutes");
    }

    if (process.ExitCode != 0)
    {
        throw new TailwindCSSCompilationException(
            $"TailwindCSS exited with code {process.ExitCode}",
            errorOutput.ToString());
    }
}

3.3 Add Custom Exception Type

public class TailwindCSSCompilationException : Exception
{
    public string? CompilerOutput { get; }
    public int? ExitCode { get; }

    public TailwindCSSCompilationException(string message, string? compilerOutput = null, int? exitCode = null)
        : base(message)
    {
        CompilerOutput = compilerOutput;
        ExitCode = exitCode;
    }
}

Phase 4: Package Quality Improvements (Priority: MEDIUM)

4.1 Update Microsoft.Build.Utilities.Core

Current: v15.9.20 (2019) Recommended: v17.x (latest for .NET 6.0+)

<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.8.3" />

4.2 Add Source Link for Debugging

<ItemGroup>
  <PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All"/>
</ItemGroup>
<PropertyGroup>
  <PublishRepositoryUrl>true</PublishRepositoryUrl>
  <EmbedUntrackedSources>true</EmbedUntrackedSources>
  <IncludeSymbols>true</IncludeSymbols>
  <SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>

4.3 Add XML Documentation

Add /// <summary> comments to all public APIs:

  • TailwindCSSTask class and properties
  • TailwindCSSCompiler.CompileAsync() method
  • TailwindCSSCompiler.GetExecutablePath() method

Phase 5: Enhanced Features (Priority: LOW)

5.1 Custom TailwindCSS Arguments

Allow users to pass additional CLI arguments:

<PropertyGroup>
  <TailwindCSSArguments>--config ./custom-config.js</TailwindCSSArguments>
</PropertyGroup>

Implementation in TailwindCSSCompiler.cs:

$"-i {InputFilename} -o {OutputFilename} --cwd {ProjectDir}" +
(isMinify ? " --minify" : "") +
(isDebug ? " --map" : "") +
(!string.IsNullOrEmpty(additionalArgs) ? $" {additionalArgs}" : "")

5.2 Multiple Compilation Support

Enable multiple TailwindCSS compilations per project:

<ItemGroup>
  <TailwindCompilation Include="main">
    <Input>$(ProjectDir)tailwind.css</Input>
    <Output>wwwroot\css\app.css</Output>
  </TailwindCompilation>
  <TailwindCompilation Include="admin">
    <Input>$(ProjectDir)admin\tailwind.css</Input>
    <Output>wwwroot\admin\css\app.css</Output>
  </TailwindCompilation>
</ItemGroup>

Implementation Checklist

Phase 1: Package Metadata (Do First)

  • Create icon.png (128x128, transparent background)
  • Add <Description> property
  • Expand <PackageTags>
  • Add <PackageProjectUrl>, <Copyright>, <DevelopmentDependency>

Phase 2: MSBuild Improvements

  • Add RunTailwindCSS conditional execution
  • Add DesignTimeBuild exclusion
  • Add property defaults in .targets
  • Refine Watch patterns (remove *.cs)

Phase 3: Error Handling

  • Add validation in TailwindCSSTask.Execute()
  • Change LogWarning to LogMessage for normal output
  • Add timeout to process execution
  • Create TailwindCSSCompilationException class
  • Improve error messages with codes (TAILWIND001, etc.)

Phase 4: Quality

  • Update Microsoft.Build.Utilities.Core to v17.x
  • Add Source Link
  • Add XML documentation comments
  • Enable symbol packages

Phase 5: Enhanced Features (Future)

  • Add TailwindCSSArguments property
  • Add multiple compilation support
  • Add configuration file support (tailwind.msbuild.json)

Comparison Summary

Feature Before After Status
Package Icon None 128x128 PNG TODO
Package Tags 1 tag 11 tags TODO
Description None Full description TODO
Conditional Execution None RunTailwindCSS property TODO
Design-time Build Exclusion None DesignTimeBuild check TODO
Property Defaults None InputFilename, IsMinify, DebugMode TODO
Input Validation None File existence, required props TODO
Process Timeout None 5 minute timeout TODO
Custom Exception Generic Exception TailwindCSSCompilationException TODO
Error Codes None TAILWIND001, TAILWIND002 TODO
MSBuild Package Version 15.9.20 17.8.3 TODO
Source Link None Microsoft.SourceLink.GitHub TODO
Symbol Package None snupkg format TODO

References