CSS és Javascript minimalizálás MSBuildből

Az ASP.NET Web Site típusú projekt egyik tulajdonsága, hogy nem tartozik hozzá project fájl. Ez ugyan többnyire előny, mert kényelmes, nekem most éppen hátrány, mert MSBuilddel akarom automatizálni nem csak a fordítási folyamatot, hanem a web.config production beállításokkal történő frissítését, a felesleges könyvtárak törlését, továbbá a CSS és Javascript fájlok minimalizálását is.

Mivel a szóban forgó alkalmazás Visual Studio 2008 alatt van és gyors megoldás kellett, ezért nem ástam bele magam a szép új MSDeployba, inkább feltettem a Web Deployments Projectset. Ez gyakorlatilag azt tudja, hogy egy Web Site projekthez rendel egy MSBuildes projekt fájlt, továbbá telepít egy rakás MSBuild taskot, ami közül néhányat grafikus felületről lehet paraméterezni.

Ha végigjutottunk a Next-Next-Finish telepítőn, akkor ne a New Project menüben keresgéljünk, hanem a Solution Explorerben a Web Site projektünkön jobb klikk és ott Add Web Deployment Project… Ezek után ne várjunk sokat, létrejön egy üres projekt, aminek a Properties ablakában szinte mindent be tudunk állítgatni. Ez többnyire magától értetődő.

A Deployment fülön tudjuk beállítani, hogy a web.config fájlunkban lévő értékek (pl. appSettings) melyik másik fájlnak a tartalmára cserélődjenek ki. Itt egy trükkre hívnám fel a figyelmet: config section groupokat nem lehet megadni. Azaz például ne próbáljuk a system.net/mailSettings szekciót cserélni, mert az épp section group, hanem az alatta lévő system.net/mailSettings/smtp szekcióval próbálkozzunk:

WDP_Deployment_tab

Ha mindent szépen beállítgattunk, akkor úgy lehet kipróbálni, hogy megbildeljük a deployment projektet.

Ám ezzel még nincs vége, ha ugyanis a deployment projekten jobb egérgombbal kattintunk és azt mondjuk, hogy Open project file, és minden bátorságunkat összeszedve belefirkálunk a forrásba, akkor még jobban felturbózhatjuk a build folyamatot.

Tekerjünk az aljára és szabadítsuk ki a kikommentezett AfterBuild szekciót. Első lépésként jó lenne megszabadulni azoktól a mappáktól és fájloktól, amik a fordítás és a web.config feldolgozása után már amúgy sem kellenek. Ehhez mindössze ezt kell beleírnunk ebbe a szekcióba:

  <Target Name="AfterBuild">
    <Message Text="-- Removing unnecessary files and folders..." Importance="high" />
    <RemoveDir Directories="$(OutputPath)App_Themes" />
    <Delete Files="$(OutputPath)web_appsettings.production.config;$(OutputPath)web_connectionstrings.production.config;$(OutputPath)web_smtp.production.config" />
  </Target>

A RemoveDir taskkal törölhetünk egy mappát, a Delete taskkal pedig fájlokat, akár többet is. A Message arra jó, hogy “fordítás” közben látszódjon a konzolon, hogy mi is történik, Importance=”high” pedig arra kell, hogy a saját üzeneteink kiemelt színnel jelenjenek meg.

Itt egyébként tetszőleges parancsot futtathatunk, ha az Exec taskot használjuk. Ha van például a projektünkben egy UserUpload mappa és az a source control miatt read-only, akkor így szedhetjük le róla ezt az attribútumot a kimenetben:

  <Exec Command="attrib -R /S &quot;$(OutputPath)UserUpload*.*&quot;" />

Ugyanígy futtathatunk tetszőleges külső alkalmazást, például olyat is, ami a Javascript fájljainkat minimalizálja. Én egy ennél igényesebb megoldást akartam és ezért döntöttem a Microsoft AJAX Minifier mellett, ahhoz ugyanis tartozik MSBuild task! Az AJAX Minifier telepítője egy MSI, én pedig nem akartam a projektben minden résztvevő kollégával ezt letölteni és telepíttetni, ezért miután a saját gépemen feltelepült, átmásoltam a szükséges fájlokat egy _Build nevű mappába a Web Site projektben. Ezt a mappát természetesen ugyanúgy letöröltetem a RemoveDir taskkal…

WDP_AJAX_Minifier

Importálnunk kell az AJAX Minifierhez tartozó MSBuild taskot, ami egyébként az AjaxMin.tasks fájlban van definiálva. Ehhez ezt kell beírnunk még az AfterBuild szekció elé:

  <Import Project="..Web_BuildAjaxMinajaxmin.tasks" />

Következő lépésben az AfterBuild szekción belül definiáltam ItemGroupot, amiben JavaScriptFiles néven összefogtam az összes tömörítendő fájlt:

  <ItemGroup>
    <JavaScriptFiles Include="$(OutputPath)Static*.js" Exclude="$(OutputPath)Static*.min.js" />
  </ItemGroup>

Ezután már csak meg kellett hívni a tömörítő taskot:

  <AjaxMin SourceFiles="@(JavaScriptFiles)" SourceExtensionPattern=".js$" TargetExtension=".min.js" />

Ez létrehozza az ize.js fájl mellé az ize.min.js fájlt. A feleslegessé vált eredeti állományt le kell törölnünk, a tömörítettet pedig át kell neveznünk:

  <Delete Files="$(OutputPath)Staticize.js" />
  <Exec Command="rename &quot;$(OutputPath)Staticize.min.js&quot; ize.js" />

Ez eddig hibátlan, sajnos azonban a Microsoft AJAX Minifier nem tud CSS-t optimalizálni. Ezért szemrebbenés nélkül letöltöttem a YUI Compressor .NET-es változatát, ahhoz ugyanis szintén van MSBuild task. A YUI Compressor nem csak CSS-t, hanem Javascriptet is tud tömöríteni, de ScottGu szerint a sajátjuk jobb, és mivel az én tesztem is ezt támasztotta alá, ezért a hibrid megoldás mellett döntöttem.

A fenti képen látszik, hogy a YUI Compressor fájljait is kicsomagoltam a _Build mappába, majd az AjaxMin.tasks mintájára faragtam egy YUICompressor.tasks fájlt, ami mindössze ennyiből áll:

  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <UsingTask TaskName="CompressorTask" AssemblyFile="Yahoo.Yui.Compressor.dll" />
  </Project>

Természetesen használat előtt ezt is importálni kell:

  <Import Project="..Web_BuildYUICompressorYUICompressor.tasks" />

És az ItemGroupot is kiegészítettem egy CssFiles változóval:

  <ItemGroup>
    <JavaScriptFiles Include="$(OutputPath)Static*.js" Exclude="$(OutputPath)Static*.min.js" />
    <CssFiles Include="$(OutputPath)Staticize.css" />
  </ItemGroup>

Ennyi bemelegítés után a CSS optimalizálás már csak ennyiből áll:

  <CompressorTask
    CssFiles="@(CssFiles)"
    DeleteCssFiles="True"
    CssOutputFile="$(OutputPath)Staticize.css"
    CssCompressionType="YuiStockCompression"
    PreserveAllSemicolons="False"
    DisableOptimizations="Nope"
    EncodingType="Default"
    LineBreakPosition="-1"            
    LoggingType="ALittleBit"
    ThreadCulture="en-au"
    IsEvalIgnored="false" />

Szerencsére itt van olyan opció (DeleteCssFiles), amivel az optimalizált verzió egyből felülírja az eredeti fájlt.

Végül már csak egyetlen lépés maradt hátra, egy rövidke .cmd fájl elkészítése, amire bármikor duplán kattintva lefordul a teljes solution (a Web Site projekt által használt osztálykönyvtárak is), és természetesen lefut a Web Deployment Project is. Ebben a batch fájlba egyetlen sor került:

  "%WinDir%Microsoft.NETFrameworkv3.5MSBuild.exe" /target:Build 
/property:Configuration=Release MySolution.sln 
/p:AspNetConfiguration=Release

Advertisements

One thought on “CSS és Javascript minimalizálás MSBuildből

  1. Visszajelzés: Web Deployment Projects fordítása Visual Studio nélkül « Balássy György szakmai blogja

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s