Skip to content

Commit cf09f20

Browse files
committed
Release v1.2.0 (#8)
Release v1.2.0 **Features** - Support for StaticAssets - Now tailwind output will be generated on build using the following default strategies: > Debug: simple file > Release: minified & optimised result **Fixes** - MsBuild project refactor, using .NET conventions - Ensuring that download directory is created
2 parents 80da3ce + 5a80ff4 commit cf09f20

File tree

23 files changed

+842
-66
lines changed

23 files changed

+842
-66
lines changed

.idea/.idea.Tailwind/.idea/indexLayout.xml

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<PropertyGroup Label="Package Properties">
3-
<Version>1.1.0</Version>
3+
<Version>1.2.0</Version>
44
<Authors>Kalleby Santos</Authors>
55
<Company>kallebysantos</Company>
66
<Product>$(MSBuildProjectName)</Product>

README.md

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,57 @@
99
</p>
1010

1111
<p align="center">
12-
<a href="https://tailwindcss.com">Tailwindcss</a> Integration for .Net.
12+
Unofficial <a href="https://tailwindcss.com">Tailwind CSS</a> Integration for .NET.
1313
</p>
1414

1515
------
16+
- [Installation](#installing-the-tailwindcss-integration)
17+
- [Configuration](#configuration)
18+
- [Examples](#examples)
19+
1620
This repository haves a pack toolset for tailwindcss integration with .Net that is based in 2 main packages, one for Hosting Startup and other for MsBuild.
1721

18-
## Instalation
19-
Just install the packages with `dotnet add Tailwind.Hosting` and `dotnet add Tailwind.Hosting.Build`
20-
Then add the following to your `Properties/launchSettings.json`
22+
## Getting Started
23+
24+
### Requirements:
25+
26+
You only need .NET, nothing more! - No `npm` neither `postcss` stuff
27+
28+
### Creating a new project
29+
30+
First of all let's create a new .Net 8 Blazor app
31+
```bash
32+
dotnet new blazor --empty -o BlazorWind -f net8.0
33+
```
34+
>Of course you can use this same guide for `mvc`, `razor` or even the legacy `webforms`
35+
36+
### Installing the Tailwindcss integration
37+
38+
Now you need to add 2 packages:
39+
40+
1. `Tailwind.Hosting`: Add support for *HotReload* when you execute `dotnet watch`
41+
2. `Tailwind.Hosting.Build`: Integrates with the *MsBuild* compiler, so it will automatically setup the tailwindcss as well generate publish ready output on `dotnet publish`
42+
```bash
43+
dotnet add package Tailwind.Hosting
44+
dotnet add package Tailwind.Hosting.Build
45+
```
46+
Finally to enable *HotReload* you only need to add the following to your `Properties/launchSettings.json`
2147
```json
22-
"environmentVariables": {
23-
"ASPNETCORE_ENVIRONMENT": "Development",
24-
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Tailwind.Hosting"
25-
}
48+
"environmentVariables": {
49+
"ASPNETCORE_ENVIRONMENT": "Development",
50+
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Tailwind.Hosting"
51+
}
52+
````
53+
54+
### Tailwindcss setup
55+
56+
This last one is related with tailwind itself. Since `v4` you only need to add the following to a `wwwroot/styles.css` file:
57+
```css
58+
@import "tailwindcss";
2659
```
27-
The available `MS build ` variables are:
2860

61+
## Configuration
62+
The Tailwind integration will automatically use the .NET conventions and the available `MsBuild` variables are:
2963
| Property | Value |
3064
|---|---|
3165
| TailwindVersion | `latest` or custom value like `3.3.5` |
@@ -36,4 +70,22 @@ The available `MS build ` variables are:
3670
| TailwindMinifyOnPublish | true |
3771
| TailwindExcludeInputFileOnPublish | true |
3872

39-
> These variables can be overwritten from your `.csproj` file, checkout the [Blazor example](examples/Blazor/Blazor.csproj)
73+
All variables can be overwritten from `.csproj`
74+
```xml
75+
<PropertyGroup Label="Tailwind.Hosting.Build Props">
76+
<TailwindVersion>latest</TailwindVersion>
77+
<TailwindWatch>true</TailwindWatch>
78+
79+
<TailwindInputCssFile>wwwroot/styles.css</TailwindInputCssFile>
80+
<TailwindOutputCssFile>wwwroot/app.css</TailwindOutputCssFile>
81+
<TailwindConfigFile>tailwind.config.js</TailwindConfigFile>
82+
83+
<TailwindMinifyOnPublish>true</TailwindMinifyOnPublish>
84+
<TailwindExcludeInputFileOnPublish>true</TailwindExcludeInputFileOnPublish>
85+
</PropertyGroup>
86+
```
87+
88+
## Examples
89+
You can find more in `examples` folder:
90+
- [Blazor example](examples/Blazor/Blazor.csproj)
91+

Tailwind.Hosting.Build/build/Tailwind.Hosting.Build.props

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,3 @@
88
AssemblyFile="$(TailwindHostingAssembly)"
99
/>
1010
</Project>
11-

Tailwind.Hosting.Build/build/Tailwind.Hosting.Build.targets

Lines changed: 70 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<PropertyGroup Label="Tailwind.Hosting Properties">
33
<TailwindVersion Condition="'$(TailwindVersion)' == ''">latest</TailwindVersion>
44
<TailwindWatch Condition="'$(TailwindWatch)' == ''">true</TailwindWatch>
5-
<TailwindMinifyOnPublish Condition="'$(TailwindMinifyOnPublish)' == ''">true</TailwindMinifyOnPublish>
5+
<TailwindMinifyOnPublish Condition="'$(TailwindMinifyOnPublish)' == '' AND '$(Configuration)' == 'Release'">true</TailwindMinifyOnPublish>
66
<TailwindExcludeInputFileOnPublish Condition="'$(TailwindExcludeInputFileOnPublish)' == ''">true</TailwindExcludeInputFileOnPublish>
77

88
<TailwindInputCssFile Condition="'$(TailwindInputCssFile)' == ''">wwwroot/styles.css</TailwindInputCssFile>
@@ -13,30 +13,87 @@
1313
<_TailwindConfig>$(OutputPath)tailwind.props.json</_TailwindConfig>
1414
</PropertyGroup>
1515

16+
<PropertyGroup Label="Tailwind.Hosting DependsOn">
17+
<BuildDependsOn>
18+
TailwindSetupExecutable;
19+
TailwindGenerateOutput;
20+
$(BuildDependsOn);
21+
</BuildDependsOn>
22+
23+
<TailwindSetupExecutableDependsOn>
24+
$(SetupExecutableDependsOn)
25+
GetTargetPath;
26+
</TailwindSetupExecutableDependsOn>
27+
28+
<TailwindGenerateOutputDependsOn>
29+
$(GenerateOutputDependsOn)
30+
TailwindSetupExecutable;
31+
</TailwindGenerateOutputDependsOn>
32+
33+
<TailwindWriteHostingConfigDependsOn>
34+
$(WriteHostingConfigDependsOn)
35+
TailwindSetupExecutable;
36+
</TailwindWriteHostingConfigDependsOn>
37+
</PropertyGroup>
38+
1639
<!--Download Tailwindcss executable-->
17-
<Target
18-
Name="SetupExecutableTask"
19-
AfterTargets="Build"
20-
Condition="!Exists('$(_TailwindExecutablePath)')"
21-
>
40+
<Target Name="TailwindSetupExecutable"
41+
DependsOnTargets="$(TailwindSetupExecutableDependsOn)"
42+
Condition="!Exists('$(_TailwindExecutablePath)')">
2243
<SetupExecutableTask
2344
TailwindExecutableFolder="$(_TailwindExecutableFolder)"
24-
TailwindVersion="$(TailwindVersion)"
25-
>
45+
TailwindVersion="$(TailwindVersion)" >
2646
<Output TaskParameter="TailwindExecutablePath" PropertyName="_TailwindExecutablePath"/>
2747
</SetupExecutableTask>
2848

2949
<ItemGroup>
3050
<Content
3151
Include="$(_TailwindExecutablePath)"
3252
CopyToOutputDirectory="PreserveNewest"
33-
CopyToPublishDirectory="Never"
34-
/>
53+
CopyToPublishDirectory="Never" />
54+
</ItemGroup>
55+
</Target>
56+
57+
<!-- Generates tailwind output on build-->
58+
<Target Name="TailwindGenerateOutput"
59+
AfterTargets="TailwindSetupExecutable"
60+
Condition="Exists('$(_TailwindExecutablePath)')"
61+
DependsOnTargets="$(TailwindGenerateOutputDependsOn)">
62+
<PropertyGroup Label="Generation Properties">
63+
<_TailwindBaseWorkingDirectory>$([System.IO.Path]::Combine('$(MSBuildProjectDirectory)', '$(TailwindWorkingDirectory)'))</_TailwindBaseWorkingDirectory>
64+
<_TailwindWorkingDirectory>$([System.IO.Path]::Combine('$(MSBuildProjectDirectory)', '$(TailwindWorkingDirectory)'))</_TailwindWorkingDirectory>
65+
<_TailwindExecutablePath>$([System.IO.Path]::Combine('$(_TailwindExecutablePath)'))</_TailwindExecutablePath>
66+
<_TailwindInputCssFile>$([System.IO.Path]::Combine('$(_TailwindBaseWorkingDirectory)', '$(TailwindInputCssFile)'))</_TailwindInputCssFile>
67+
<_TailwindOutputCssFile>$([System.IO.Path]::Combine('$(_TailwindBaseWorkingDirectory)', '$(TailwindOutputCssFile)'))</_TailwindOutputCssFile>
68+
<_TailwindTailwindConfigFile>$([System.IO.Path]::Combine('$(_TailwindBaseWorkingDirectory)', '$(TailwindConfigFile)'))</_TailwindTailwindConfigFile>
69+
70+
<_TailwindGenerateCommand>$(_TailwindExecutablePath) -c $(_TailwindTailwindConfigFile) -i $(_TailwindInputCssFile) -o $(_TailwindOutputCssFile)</_TailwindGenerateCommand>
71+
<_TailwindGenerateCommand Condition="'$(Configuration)' == 'Release' AND '$(TailwindMinifyOnPublish)' == 'true'">
72+
$(_TailwindGenerateCommand) --minify
73+
</_TailwindGenerateCommand>
74+
</PropertyGroup>
75+
<Exec Command="$(_TailwindGenerateCommand)" WorkingDirectory="$(_TailwindBaseWorkingDirectory)"/>
76+
<!-- Includes the generated file to project references
77+
NOTE(kallebysantos): For .NET 9+ we need to make sure that this file is included before 'ResolveStaticWebAssetsInputs'
78+
-->
79+
<ItemGroup>
80+
<!-- Removes old build cached file reference -->
81+
<Content Remove="$(TailwindOutputCssFile)"/>
82+
83+
<Content Include="$(TailwindOutputCssFile)"
84+
CopyToPublishDirectory="Always"/>
3585
</ItemGroup>
3686
</Target>
3787

38-
<!--Create Tailwind configuration props file-->
39-
<Target Name="WriteTailwindConfiguration" AfterTargets="SetupExecutableTask" DependsOnTargets="SetupExecutableTask">
88+
<ItemGroup Condition="'$(TailwindExcludeInputFileOnPublish)' == 'true'">
89+
<Content Remove="$(TailwindInputCssFile)" CopyToPublishDirectory="Never"/>
90+
<None Remove="$(TailwindInputCssFile)" CopyToPublishDirectory="Never"/>
91+
</ItemGroup>
92+
93+
<!--Create Tailwind.Hosting configuration file-->
94+
<Target Name="TailwindWriteHostingConfig"
95+
AfterTargets="Build"
96+
DependsOnTargets="$(TailwindWriteHostingConfigDependsOn)">
4097
<PropertyGroup Label="Tailwind.Hosting Json Config File Properties">
4198
<_TailwindBaseWorkingDirectory>$([System.IO.Path]::Combine('$(MSBuildProjectDirectory)', '$(TailwindWorkingDirectory)'))</_TailwindBaseWorkingDirectory>
4299
<_TailwindWorkingDirectory>$([System.IO.Path]::Combine('$(MSBuildProjectDirectory)', '$(TailwindWorkingDirectory)').Replace('\','\\'))</_TailwindWorkingDirectory>
@@ -68,40 +125,8 @@
68125
</ItemGroup>
69126
</Target>
70127

71-
<!-- Generates a minified output on publish -->
72-
<Target Name="GenerateMinifiedTailwindOutput"
73-
AfterTargets="ComputeFilesToPublish"
74-
Condition="Exists('$(_TailwindExecutablePath)') AND '$(TailwindMinifyOnPublish)' == 'true'"
75-
DependsOnTargets="SetupExecutableTask">
76-
<PropertyGroup Label="Tailwind.Hosting Generation Properties">
77-
<_TailwindBaseWorkingDirectory>$([System.IO.Path]::Combine('$(MSBuildProjectDirectory)', '$(TailwindWorkingDirectory)'))</_TailwindBaseWorkingDirectory>
78-
<_TailwindWorkingDirectory>$([System.IO.Path]::Combine('$(MSBuildProjectDirectory)', '$(TailwindWorkingDirectory)'))</_TailwindWorkingDirectory>
79-
<_TailwindExecutablePath>$([System.IO.Path]::Combine('$(_TailwindExecutablePath)'))</_TailwindExecutablePath>
80-
<_TailwindInputCssFile>$([System.IO.Path]::Combine('$(_TailwindBaseWorkingDirectory)', '$(TailwindInputCssFile)'))</_TailwindInputCssFile>
81-
<_TailwindOutputCssFile>$([System.IO.Path]::Combine('$(OutputPath)', '$(TailwindOutputCssFile)'))</_TailwindOutputCssFile>
82-
<_TailwindTailwindConfigFile>$([System.IO.Path]::Combine('$(_TailwindBaseWorkingDirectory)', '$(TailwindConfigFile)'))</_TailwindTailwindConfigFile>
83-
84-
<_TailwindGenerateCommand>$(_TailwindExecutablePath) -m -c $(_TailwindTailwindConfigFile) -i $(_TailwindInputCssFile) -o $(_TailwindOutputCssFile)</_TailwindGenerateCommand>
85-
</PropertyGroup>
86-
87-
<Exec Command="$(_TailwindGenerateCommand)" WorkingDirectory="$(_TailwindBaseWorkingDirectory)"/>
88-
89-
<ItemGroup>
90-
<ResolvedFileToPublish Include="$(_TailwindOutputCssFile)">
91-
<RelativePath>$(TailwindOutputCssFile)</RelativePath>
92-
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
93-
<ExcludeFromSingleFile>false</ExcludeFromSingleFile>
94-
</ResolvedFileToPublish>
95-
</ItemGroup>
96-
</Target>
97-
98-
<ItemGroup Condition="'$(TailwindExcludeInputFileOnPublish)' == 'true'">
99-
<Content Remove="$(TailwindInputCssFile)" CopyToPublishDirectory="Never"/>
100-
<None Remove="$(TailwindInputCssFile)" CopyToPublishDirectory="Never"/>
101-
</ItemGroup>
102-
103128
<!--The generated file is deleted after a general clean. It will force the regeneration on rebuild-->
104-
<Target Name="AfterClean">
129+
<Target Name="_TailwindClean" AfterTargets="Clean">
105130
<ItemGroup>
106131
<TailwindFilesToDelete Include="$(OutputPath)tailwind*"/>
107132
</ItemGroup>

Tailwind.Hosting.Cli/TailwindManager.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ string tailwindExecutablePath
6060
await httpClient.GetAsync(tailwindExecutableUrl)
6161
).EnsureSuccessStatusCode();
6262

63+
// Ensure path exists
64+
Directory.CreateDirectory(Path.GetDirectoryName(tailwindExecutablePath)!);
65+
6366
using var fileStream = File.Create(tailwindExecutablePath);
6467
await response.Content.CopyToAsync(fileStream);
6568

Tailwind.sln

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
44
VisualStudioVersion = 17.0.31903.59
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{5D8C1823-0A68-4E21-901F-1EB2F497299F}"
7+
ProjectSection(SolutionItems) = preProject
8+
examples\tailwind.config.js = examples\tailwind.config.js
9+
EndProjectSection
710
EndProject
811
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blazor", "examples\Blazor\Blazor.csproj", "{7358A5E5-68A2-4767-8FEF-F10886ACAD47}"
912
EndProject
@@ -13,6 +16,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tailwind.Hosting.Build", "T
1316
EndProject
1417
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tailwind.Hosting.Cli", "Tailwind.Hosting.Cli\Tailwind.Hosting.Cli.csproj", "{699FACBD-FB06-4B4F-914C-8242A0C1D1C3}"
1518
EndProject
19+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlazorStaticAssets", "examples\BlazorStaticAssets\BlazorStaticAssets.csproj", "{AC4BA667-509A-448A-8A5E-C4B0B8CC4B13}"
20+
EndProject
1621
Global
1722
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1823
Debug|Any CPU = Debug|Any CPU
@@ -38,8 +43,13 @@ Global
3843
{699FACBD-FB06-4B4F-914C-8242A0C1D1C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
3944
{699FACBD-FB06-4B4F-914C-8242A0C1D1C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
4045
{699FACBD-FB06-4B4F-914C-8242A0C1D1C3}.Release|Any CPU.Build.0 = Release|Any CPU
46+
{AC4BA667-509A-448A-8A5E-C4B0B8CC4B13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
47+
{AC4BA667-509A-448A-8A5E-C4B0B8CC4B13}.Debug|Any CPU.Build.0 = Debug|Any CPU
48+
{AC4BA667-509A-448A-8A5E-C4B0B8CC4B13}.Release|Any CPU.ActiveCfg = Release|Any CPU
49+
{AC4BA667-509A-448A-8A5E-C4B0B8CC4B13}.Release|Any CPU.Build.0 = Release|Any CPU
4150
EndGlobalSection
4251
GlobalSection(NestedProjects) = preSolution
4352
{7358A5E5-68A2-4767-8FEF-F10886ACAD47} = {5D8C1823-0A68-4E21-901F-1EB2F497299F}
53+
{AC4BA667-509A-448A-8A5E-C4B0B8CC4B13} = {5D8C1823-0A68-4E21-901F-1EB2F497299F}
4454
EndGlobalSection
4555
EndGlobal

compile_lib.sh

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1+
PROJECT=$1
2+
13
rm -R ~/.nuget/packages/tailwind.hosting
24
rm -R ~/.nuget/packages/tailwind.hosting.build
35
rm -R ~/.nuget/packages/tailwind.hosting.cli
46

5-
rm -R ./examples/Blazor/bin/
6-
rm -R ./examples/Blazor/obj/
7+
rm -R "${PROJECT:?}/bin/"
8+
rm -R "${PROJECT:?}/obj/"
79
rm -R ./nupkgs/*
810

911
dotnet clean
10-
dotnet remove examples/Blazor package Tailwind.Hosting
11-
dotnet remove examples/Blazor package Tailwind.Hosting.Build
12+
dotnet remove "$PROJECT" package Tailwind.Hosting
13+
dotnet remove "$PROJECT" package Tailwind.Hosting.Build
1214

1315
dotnet build
1416
dotnet pack Tailwind.Hosting
1517
dotnet pack Tailwind.Hosting.Build
1618
dotnet pack Tailwind.Hosting.Cli
1719

18-
dotnet add examples/Blazor package Tailwind.Hosting
19-
dotnet add examples/Blazor package Tailwind.Hosting.Build
20+
dotnet add "$PROJECT" package Tailwind.Hosting
21+
dotnet add "$PROJECT" package Tailwind.Hosting.Build

examples/Blazor/Blazor.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
</PropertyGroup>
2020

2121
<ItemGroup>
22-
<PackageReference Include="Tailwind.Hosting" Version="1.1.0" />
23-
<PackageReference Include="Tailwind.Hosting.Build" Version="1.1.0">
22+
<PackageReference Include="Tailwind.Hosting" Version="1.2.0" />
23+
<PackageReference Include="Tailwind.Hosting.Build" Version="1.2.0">
2424
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2525
<PrivateAssets>all</PrivateAssets>
2626
</PackageReference>

0 commit comments

Comments
 (0)