Combine Multiple css Files into One File and Minify css and javascipt using Nant
Introduction
When you use multiple css files in project , for each css file it makes extra HTTP request to server. Even though you use ASP.NET theme it breaks out into multiple css files. Also if you minimize the size of css files then your page will load faster.
Background
In development time you might want to organize css into multiple files and with proper whitespace and comments. But you should keep in mind that Internet Explorer 6, 7 do not support more than 31 css files in a single page. In case of deployment you can combine multiple css files into single css file and also minimize size of file using minifier like YUI compressor for loading your page faster. Here I have given a way to combine multiple css files and also minify css and javascript files.
Implemenation
If you use ASP.NET theme then there would not have any direct reference of css link in your page. So combining multiple css files into a single files does not effect application wide. You can combine multiple javascript files into one using composite script references in the Script Manager Combining Client Scripts into a Composite Script. Here I will discussion only deployment time process which help to load your page faster. So I only minify javascript files using Nant.
For automating all these processes I used NAnt tool. Combining multiple files into one file is easy in NAnt using Nant tasks. Also for minifying css and javascript files I used YUI compressor.
First I discuss process steps before going to example:
-
combine all css files into one files. NAnt give you a easy way to do this using Nant concat task.
-
After combining multiple css files and javascript files are minified using YUI compressor. YUI compressor safely minimizes your css and javacript file size.
-
Add created single css file in project and remove other unused css files from project reference. So that It does not break your setup and after deployment you get only one compressed css files.
I have attached my Nant.build file here and in my previous two articles Work Flow of Build Automation and Automate Publishing a WebSite into IIS using MSDeploy and NAnt Scripts I have discussed steps of my build process and also there i have described NAnt scripts.
In this articles I am using same script and will describe about scripts which combine css files and minify javascipts and css files.
I have given code block which combine multiple css files into single style.css files and delete other css files from Theme folder.
Multiple files can be concatenated using Nant concat task wich is found after loading Nant contrib.Task.dll and for that you need to have NAnt contrib dll registered or you can add <loadtasks assembly="${NAntContrib}\NAnt.Contrib.Tasks.dll" /> before calling <concat> task.
<target name="css" description="Concatenate CSS source files"> <loadtasks assembly="${NAntContrib}\NAnt.Contrib.Tasks.dll" /> <echo message="Building ${BuildDir}\${CssFileLocation}\style.css" /> <concat destfile="${BuildDir}\${CssFileLocation}\style.css" append="true"> <fileset> <include name="${BuildDir}\${CssFileLocation}\*.css" /> <exclude name ="${BuildDir}\${CssFileLocation}\default.css"/> </fileset> </concat> <echo message="${BuildDir}\${CssFileLocation}\style.css built." /> <echo message="delete other files except style.css" /> <delete> <fileset> <include name="${BuildDir}\${CssFileLocation}\*.css"/> <exclude name="${BuildDir}\${CssFileLocation}\style.css"/> <exclude name ="${BuildDir}\${CssFileLocation}\default.css"/> </fileset> </delete> <echo message="delete other files except style.css is done" /> </target>
In theme folder I had seven css files. you can see css files in CssFileLocation folder is concatenated into a single style.css file but here I also have excluded default.css file. You might have a css file that will be loaded dynamically and have alternate style which style.css contains. So I have excluded default.css file in my project.After this operation I have only two css files under CssFileLocation which are style.css and default.css.
For minimizing the size of css files and javascipts files I used YUI compressor. The article YUI Compressor and NAnt nice scripts file for minifying css and javascipts and I also took help from those code. here my code :
<target name="JavaScript.minify"> <foreach item="File" property="filename"> <in> <items> <include name="${BuildDir}\${JsFileLocation}\**\*.js"/> <exclude name ="${BuildDir}\${JsFileLocation}\jquery.min.js"/> <exclude name ="${BuildDir}\${JsFileLocation}\jquery.min-vsdoc.js"/> <exclude name ="${BuildDir}\${JsFileLocation}\jquery-ui.custom.min.js"/> </items> </in> <do> <echo message="${filename}" /> <exec program="java"> <arg value="-jar" /> <arg value="${YUI}" /> <arg value="--type" /> <arg value="js" /> <arg value="-o" /> <arg value="${filename}.min" /> <arg value="${filename}" /> </exec> <move file="${filename}.min" tofile="${filename}" overwrite="true" /> </do> </foreach> </target>
Here I have excluded minifying jquery.min.*.js files as they are already minified. Also the css minifying code :
<target name="css.minify" depends="css" description="Minimize CSS files"> <foreach item="File" property="filename"> <in> <items> <include name="${BuildDir}\${CssFileLocation}\**\*.css"/> </items> </in> <do> <echo message="${filename}" /> <exec program="java"> <arg value="-jar" /> <arg value="${YUI}" /> <arg value="-o" /> <arg value="${filename}.min" /> <arg value="${filename}" /> </exec> <move file="${filename}.min" tofile="${filename}" overwrite="true" /> </do> </foreach> </target>
But the problem is I had 7 css files under CssFileLocation folder which is
the location of Theme folder. I have removed 6 css files expect default.css in
my 'css' target but these files still have references in my web
project file with <Content include="App_theme\Base\xxx.css"\> tag. So
after above operations it will give error when you create setup as content files
are missing in your source project. So before you build your solution you have
to remove the references of those removed css files. I have used C# code for
removing those references in WebProject.cproj.
This code first finds all references of css files in web project and then removes these references and also adds new style.css reference.
<target name="ReplaceCss"> <property name="filename" value="${BuildDir}\Development\Client\Web\WebProject.csproj" /> <script language="C#"> <code> <![CDATA[ public static void ScriptMain(Project project) { StreamReader projectFileReader = new StreamReader(project.Properties["filename"]); string x = @"<Content Include=\""App_Themes\\Base\\(?!Default)[\w-]*.css\"" />"; string output = @"<Content Include='App_Themes\Base\style.css'/>"; Regex sourcePathRegx = new Regex(x); string projectFile; try { projectFile = projectFileReader.ReadToEnd(); } finally { projectFileReader.Close(); } MatchCollection match = sourcePathRegx.Matches(projectFile); if(match.Count>0) { int i = 0; foreach (Match collection in match) { if(i==0) { projectFile = projectFile.Replace(collection.Value, output); } else { projectFile = projectFile.Replace(collection.Value, string.Empty); } i++; } } StreamWriter projectFileWriter = new StreamWriter(project.Properties["filename"]); try { projectFileWriter.Write(projectFile); } finally { projectFileWriter.Close(); } } ]]> </code> </script> </target>
And as all these script need to run before creating build of solution so I have called these targets before creating build using MSbuild.
<target name="BuildPublish" depends="setversion"> <call target = "css.minify"/> <call target = "JavaScript.minify"/> <call target = "ReplaceCss"/> <echo message="Build solution"/> <exec program="${MSBuildPath}"> <arg value="${BuildDir}\${SolutionFileName}" /> <arg value="/property:Configuration=release" /> <arg value="/t:Rebuild" /> </exec> </target>
So after all these operation you have only two minified css files in which style.css file is combination of 6 css files in your project. So now you have only two HTTP requests to server where before it was seven HTTP requests. Also javacript codes are minified.
Point of Interest
The advantage of this process is that you are mantaining separate css files according to your module and also javascript , css files are readable with proper alignment as spaces. And only creating build of solution using automated build minifying and combining css and javascripts. So it does not hamper your css and javacsript organization.
发表评论
has been be of and. Hence, by different growing home PCOS. Stress sure it was growth sea some.