使用 Nant 将多个 CSS 文件合并为一个文件并最小化 CSS 和 JavaScript






4.52/5 (8投票s)
如何将多个 CSS 文件合并,以及在自动化构建中使用 NAnt 时最小化 CSS 和 JavaScript。
引言
当您在项目中使用了多个 CSS 文件时,每个 CSS 文件都会向服务器发出额外的 HTTP 请求。即使您使用 ASP.NET 主题,它也会分散成多个 CSS 文件。此外,如果您减小 CSS 文件的大小,您的页面加载速度将会更快。
背景
在开发期间,您可能希望将 CSS 组织成多个文件,并带有适当的空格和注释。但是您需要记住,Internet Explorer 6、7 在单个页面中不支持超过 31 个 CSS 文件。在部署时,您可以将多个 CSS 文件合并为一个 CSS 文件,并使用像 YUI compressor 这样的压缩器来减小文件大小,从而更快地加载您的页面。在这里,我提供了一种合并多个 CSS 文件并压缩 CSS 和 JavaScript 文件的方法。
实现
如果您使用 ASP.NET 主题,那么您的页面中将不会有 CSS 链接的直接引用。因此,将多个 CSS 文件合并到一个文件中不会影响整个应用程序。您可以使用 Script Manager 中的复合脚本引用将多个 JavaScript 文件合并到一个文件中 将客户端脚本合并为复合脚本。在这里,我只讨论部署时的过程,这将有助于更快地加载您的页面。所以,我只使用 Nant 来压缩 JavaScript 文件。
为了自动化所有这些过程,我使用了 NAnt 工具。使用 NAnt 中的 Nant 任务可以轻松地将多个文件合并为一个文件。我还使用 YUI compressor 来压缩 CSS 和 JavaScript 文件。
首先,我将在举例之前讨论过程步骤。
-
将所有 CSS 文件合并为一个文件。NAnt 通过 Nant concat 任务为您提供了一种简单的方法。
-
合并多个 CSS 文件后,JavaScript 文件将使用 YUI compressor 进行压缩。YUI compressor 可以安全地减小您的 CSS 和 JavaScript 文件的大小。
-
在项目中创建单个 CSS 文件,并从项目中移除其他未使用的 CSS 文件引用,这样就不会破坏您的设置,并且在部署后您将只有一个压缩后的 CSS 文件。
我在此处附上了我的Nant.build 文件,并且在我之前的两篇文章中,构建自动化的工作流程 和 使用 MSDeploy 和 NAnt 脚本自动发布网站到 IIS,我讨论了我的构建过程的步骤,并在那里描述了 NAnt 脚本。
在本文中,我将使用相同的脚本,并介绍合并 CSS 文件以及压缩 JavaScript 和 CSS 文件的脚本。
我提供了一个代码块,它将多个 CSS 文件合并到一个名为style.css 的文件中,并删除Theme 文件夹中的其他 CSS 文件。
可以使用 Nant concat 任务连接多个文件,该任务在加载 Nant contrib.Task.dll 后可用,为此,您需要注册 NAnt contrib DLL,或者您可以在调用 <concat>
任务之前添加 <loadtasks assembly="${NAntContrib}\NAnt.Contrib.Tasks.dll" />
。
<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>
在 theme 文件夹中,我有七个 CSS 文件。您可以看到 CssFileLocation 文件夹中的 CSS 文件被合并到一个名为 style.css 的文件中,但在这里我也排除了 default.css 文件。您可能有一个 CSS 文件将动态加载并具有替代样式,而 style.css 包含这些。所以我排除了项目中的 default.css 文件。在此操作之后,CssFileLocation 文件夹下只有两个 CSS 文件:style.css 和 default.css。
为了减小 CSS 文件和 JavaScript 文件的大小,我使用了 YUI compressor。文章 YUI Compressor and NAnt 提供了用于压缩 CSS 和 JavaScript 的优秀脚本文件,我也从中借鉴了代码。这是我的代码
<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>
在这里,我排除了对jquery.min.*.js 文件的压缩,因为它们已经经过压缩。还有 CSS 压缩代码
<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>
但问题是,我在CssFileLocation 文件夹(即Theme 文件夹的位置)下有 7 个 CSS 文件。我在我的 'css
' 目标中移除了 6 个 CSS 文件 - 除了 default.css - 但这些文件仍然在我的 Web 项目文件中被引用,带有 <Content include="App_theme\Base\xxx.css"\>
标签。因此,在执行上述操作后,当您创建设置时,由于源项目中缺少内容文件,将会出现错误。因此,在构建解决方案之前,您必须删除这些已移除 CSS 文件的引用。我使用了 C# 代码来删除WebProject.cproj 中的这些引用。
此代码首先查找 Web 项目中所有 CSS 文件的引用,然后删除这些引用,并添加新的style.css 引用。
<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>
由于所有这些脚本需要在创建解决方案构建之前运行,因此我使用 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>
因此,在所有这些操作之后,您的项目中只有两个压缩后的 CSS 文件,其中style.css 文件是您项目中 6 个 CSS 文件的组合。现在,您只需要向服务器发出两次 HTTP 请求,而之前是七次。JavaScript 代码也得到了压缩。
看点
这个过程的好处在于,您可以根据模块维护独立的 CSS 文件,并且 JavaScript、CSS 文件具有良好的对齐和可读性。并且只有在创建解决方案构建时才通过自动化的构建来压缩和合并 CSS 和 JavaScript。因此,它不会影响您的 CSS 和 JavaScript 组织。