Implemented Tailwind CSS class list extraction and integrated it into the build process of the frontend package #2

Merged
ChiaraBm merged 1 commits from feat/AddCssClassList into v2.1 2026-01-14 15:10:31 +00:00
8 changed files with 78 additions and 15 deletions

View File

@@ -32,6 +32,10 @@ jobs:
run: rm -rf ./artifacts
# Publish frontend
- name: Build tailwind styles and extract class list
working-directory: Hosts/Moonlight.Frontend.Host/Styles
run: npm run build
- name: Build project
run: dotnet build Moonlight.Frontend --configuration Debug

View File

@@ -14,11 +14,11 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.1"/>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="10.0.1" PrivateAssets="all"/>
<PackageReference Include="MoonCore.PluginFramework" Version="1.0.9" />
<PackageReference Include="MoonCore.PluginFramework.Generator" Version="1.0.3" />
<PackageReference Include="MoonCore.PluginFramework" Version="1.0.9"/>
<PackageReference Include="MoonCore.PluginFramework.Generator" Version="1.0.3"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Moonlight.Frontend\Moonlight.Frontend.csproj" />
<ProjectReference Include="..\..\Moonlight.Frontend\Moonlight.Frontend.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,25 @@
import fs from 'fs';
import selectorParser from 'postcss-selector-parser';
export default function extractTailwindClasses(opts = {}) {
const classSet = new Set();
return {
postcssPlugin: 'extract-tailwind-classes',
Rule(rule) {
selectorParser(selectors => {
selectors.walkClasses(node => {
classSet.add(node.value);
});
}).processSync(rule.selector);
},
OnceExit() {
const classArray = Array.from(classSet).sort();
fs.mkdirSync('../../../Moonlight.Frontend/Styles', { recursive: true });
fs.writeFileSync('../../../Moonlight.Frontend/Styles/Moonlight.Frontend.map', classArray.join('\n'));
console.log(`Extracted classes ${classArray.length}`);
}
};
}
extractTailwindClasses.postcss = true;

View File

@@ -1,15 +1,20 @@
{
"scripts": {
"tailwind": "npx postcss styles.css -o ../wwwroot/style.min.css --watch",
"tailwind-build": "npx postcss styles.css -o ../wwwroot/style.min.css"
"dev": "npx postcss styles.css -o ../wwwroot/style.min.css --watch",
"dev-build": "npx postcss styles.css -o ../wwwroot/style.min.css",
"build": "cross-env EXTRACT_CLASSES=true npx postcss styles.css -o ../wwwroot/style.min.css"
},
"dependencies": {
"@tailwindcss/postcss": "^4.1.18",
"cssnano": "^7.1.2",
"postcss": "^8.5.6",
"postcss-cli": "^11.0.1",
"postcss-selector-parser": "^7.1.1",
"shadcnblazor": "^1.0.5",
"tailwindcss": "^4.1.18",
"tw-animate-css": "^1.4.0"
},
"devDependencies": {
"cross-env": "^10.1.0"
}
}

View File

@@ -1,8 +1,18 @@
export default {
plugins: {
"@tailwindcss/postcss": {},
"cssnano":{
preset: 'default'
}
}
}
import tailwindcss from '@tailwindcss/postcss';
import cssnano from 'cssnano';
import extractTailwindClasses from './extract-classes.mjs';
const plugins = [
tailwindcss,
cssnano({
preset: 'default'
})
];
if (process.env.EXTRACT_CLASSES === "true") {
plugins.push(extractTailwindClasses());
}
export default {
plugins
};

View File

@@ -23,7 +23,6 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="10.0.1"/>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.1"/>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="10.0.1" PrivateAssets="all"/>
<PackageReference Include="Riok.Mapperly" Version="4.3.1-next.0"/>
<PackageReference Include="ShadcnBlazor" Version="1.0.5" />
<PackageReference Include="ShadcnBlazor.Extras" Version="1.0.5" />
@@ -32,5 +31,9 @@
<ItemGroup>
<ProjectReference Include="..\Moonlight.Shared\Moonlight.Shared.csproj"/>
</ItemGroup>
<ItemGroup>
<None Include="Styles/*" Pack="true" PackagePath="Styles/" />
<None Include="Moonlight.Frontend.targets" Pack="true" PackagePath="build\Moonlight.Frontend.targets" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,15 @@
<Project>
<PropertyGroup>
<MoonlightCssClassDir Condition="'$(MoonlightCssClassDir)' == ''">
$(MSBuildProjectDirectory)\bin\Moonlight.Frontend
</MoonlightCssClassDir>
</PropertyGroup>
<Target Name="CopyContents" BeforeTargets="Build">
<ItemGroup>
<Files Include="$(MSBuildThisFileDirectory)..\Styles\**\*" />
</ItemGroup>
<Copy SourceFiles="@(Files)" DestinationFolder="$(MoonlightCssClassDir)" SkipUnchangedFiles="true" />
</Target>
</Project>

View File

@@ -0,0 +1 @@
THIS WILL BE GENERATED ON PACKAGE BUILD