我怎样才能自动压缩和最小化ASP.NET MVC应用程序中的JavaScript文件?

所以我有一个ASP.NET MVC应用程序,在不同的地方引用了一些JavaScript文件(在站点的主人和其他几个视图中的引用)。

我想知道是否有一种自动的方式来压缩和尽可能最小化这样的引用到一个单一的.js文件。 这样…

<script src="<%= ResolveUrl("~") %>Content/ExtJS/Ext.ux.grid.GridSummary/Ext.ux.grid.GridSummary.js" type="text/javascript"></script> <script src="<%= ResolveUrl("~") %>Content/ExtJS/ext.ux.rating/ext.ux.ratingplugin.js" type="text/javascript"></script> <script src="<%= ResolveUrl("~") %>Content/ExtJS/ext-starslider/ext-starslider.js" type="text/javascript"></script> <script src="<%= ResolveUrl("~") %>Content/ExtJS/ext.ux.dollarfield.js" type="text/javascript"></script> <script src="<%= ResolveUrl("~") %>Content/ExtJS/ext.ux.combobox.js" type="text/javascript"></script> <script src="<%= ResolveUrl("~") %>Content/ExtJS/ext.ux.datepickerplus/ext.ux.datepickerplus-min.js" type="text/javascript"></script> <script src="<%= ResolveUrl("~") %>Content/ExtJS/SessionProvider.js" type="text/javascript"></script> <script src="<%= ResolveUrl("~") %>Content/ExtJS/TabCloseMenu.js" type="text/javascript"></script> <script src="<%= ResolveUrl("~") %>Content/ActivityViewer/ActivityForm.js" type="text/javascript"></script> <script src="<%= ResolveUrl("~") %>Content/ActivityViewer/UserForm.js" type="text/javascript"></script> <script src="<%= ResolveUrl("~") %>Content/ActivityViewer/SwappedGrid.js" type="text/javascript"></script> <script src="<%= ResolveUrl("~") %>Content/ActivityViewer/Tree.js" type="text/javascript"></script> 

…可以减less到这样的事情…

 <script src="<%= ResolveUrl("~") %>Content/MyViewPage-min.js" type="text/javascript"></script> 

谢谢

我个人认为在开发过程中保持文件的分离是非常宝贵的,在生产过程中,这种情况非常重要。 所以我修改了我的部署脚本为了做到这一点。

我有一个部分是这样写的:

 <Target Name="BeforeDeploy"> <ReadLinesFromFile File="%(JsFile.Identity)"> <Output TaskParameter="Lines" ItemName="JsLines"/> </ReadLinesFromFile> <WriteLinesToFile File="Scripts\all.js" Lines="@(JsLines)" Overwrite="true"/> <Exec Command="java -jar tools\yuicompressor-2.4.2.jar Scripts\all.js -o Scripts\all-min.js"></Exec> </Target> 

并在我的主页面文件中使用:

 if (HttpContext.Current.IsDebuggingEnabled) {%> <script type="text/javascript" src="<%=Url.UrlLoadScript("~/Scripts/jquery-1.3.2.js")%>"></script> <script type="text/javascript" src="<%=Url.UrlLoadScript("~/Scripts/jquery-ui-1.7.2.min.js")%>"></script> <script type="text/javascript" src="<%=Url.UrlLoadScript("~/Scripts/jquery.form.js")%>"></script> <script type="text/javascript" src="<%=Url.UrlLoadScript("~/Scripts/jquery.metadata.js")%>"></script> <script type="text/javascript" src="<%=Url.UrlLoadScript("~/Scripts/jquery.validate.js")%>"></script> <script type="text/javascript" src="<%=Url.UrlLoadScript("~/Scripts/additional-methods.js")%>"></script> <script type="text/javascript" src="<%=Url.UrlLoadScript("~/Scripts/form-interaction.js")%>"></script> <script type="text/javascript" src="<%=Url.UrlLoadScript("~/Scripts/morevalidation.js")%>"></script> <script type="text/javascript" src="<%=Url.UrlLoadScript("~/Scripts/showdown.js") %>"></script> <% } else {%> <script type="text/javascript" src="<%=Url.UrlLoadScript("~/Scripts/all-min.js")%>"></script> <% } %> 

构build脚本获取该部分中的所有文件并将它们组合在一起。 然后我使用YUI的缩小器来获得javascript的缩小版本。 因为这是由IIS提供的,所以我宁愿打开IIS中的压缩来获得gzip压缩。 ****添加****我的部署脚本是一个MSBuild脚本。 我也使用优秀的MSBuild社区任务( http://msbuildtasks.tigris.org/ )来帮助部署一个应用程序。

我不打算在这里发布我的整个脚本文件,但是这里有一些相关的行应该展示它的大部分function。

以下部分将在asp.net编译器中运行构build以将应用程序复制到目标驱动器。 (在上一步中,我只是运行exec net use命令并映射networking共享驱动器)。

 <Target Name="Precompile" DependsOnTargets="build;remoteconnect;GetTime"> <MakeDir Directories="%(WebApplication.SharePath)\$(buildDate)" /> <Message Text="Precompiling Website to %(WebApplication.SharePath)\$(buildDate)" /> <AspNetCompiler VirtualPath="/%(WebApplication.VirtualDirectoryPath)" PhysicalPath="%(WebApplication.PhysicalPath)" TargetPath="%(WebApplication.SharePath)\$(buildDate)" Force="true" Updateable="true" Debug="$(Debug)" /> <Message Text="copying the correct configuration files over" /> <Exec Command="xcopy $(ConfigurationPath) %(WebApplication.SharePath)\$(buildDate) /S /E /Y" /> </Target> 

所有的解决scheme项目被复制后,我运行这个:

  <Target Name="_deploy"> <Message Text="Removing Old Virtual Directory" /> <WebDirectoryDelete VirtualDirectoryName="%(WebApplication.VirtualDirectoryPath)" ServerName="$(IISServer)" ContinueOnError="true" Username="$(username)" HostHeaderName="$(HostHeader)" /> <Message Text="Creating New Virtual Directory" /> <WebDirectoryCreate VirtualDirectoryName="%(WebApplication.VirtualDirectoryPath)" VirtualDirectoryPhysicalPath="%(WebApplication.IISPath)\$(buildDate)" ServerName="$(IISServer)" EnableDefaultDoc="true" DefaultDoc="%(WebApplication.DefaultDocument)" Username="$(username)" HostHeaderName="$(HostHeader)" /> </Target> 

这应该足以让您开始自动化部署。 我把所有这些东西放在一个名为Aspnetdeploy.msbuild的独立文件中。 我只是msbuild / t:每当我需要部署到一个环境的目标。

实际上,使用Web部署项目 (WDP)有一个更简单的方法。 WDP将pipe理aspnet_compileraspnet_merge工具的复杂性。 您可以通过Visual Studio中的UI来自定义stream程。

至于压缩js文件,你可以保留所有的js文件,并在构build过程中压缩这些文件。 所以在WDP中你会声明这样的东西:

 <Project> REMOVE CONTENT HERE FOR WEB <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" /> <!-- Extend the build process --> <PropertyGroup> <BuildDependsOn> $(BuildDependsOn); CompressJavascript </BuildDependsOn> </PropertyGroup> <Target Name="CompressJavascript"> <ItemGroup> <_JSFilesToCompress Include="$(OutputPath)Scripts\**\*.js" /> </ItemGroup> <Message Text="Compresing Javascript files" Importance="high" /> <JSCompress Files="@(_JSFilesToCompress)" /> </Target> </Project> 

这使用MSBuild社区任务中的JSCompress MSBuild 任务 ,我认为这是基于JSMin的。

这个想法是,让所有的js文件保持原样(即可debugging/可读) 。 在构buildWDP时,首先将js文件复制到OutputPath ,然后调用CompressJavascript目标以最小化js文件。 这不会修改您的原始源文件,只是WDP项目的输出文件夹中的文件。 然后,将文件部署到WDP输出path中,其中包括预编译的站点。 我在书中介绍了这个确切的情况(链接在我的名字下面)

您还可以让WDP处理创build虚拟目录,只需选中一个checkbox并填写虚拟目录的名称即可。

对于MSBuild上的一些链接:

  • 在MSBuild里面
  • 7步到MSBuild
  • MSDN MSBuild文档

说易卜拉欣Hashimi

我的书: Microsoft Build Engine内部:使用MSBuild和Team Foundation Build

Scott Hanselman最近在博客中介绍了如何将脚本合并到静态文件 ,基本上使用带有CompositeScript引用和Path属性的ScriptManager

 <asp:ScriptManager runat="server"> <CompositeScript path="http://www.example.com/1.js"> <Scripts> <asp:ScriptReference /> <asp:ScriptReference /> <!-- etc. --> </Scripts> </CompositeScript> </asp:ScriptManager> 

在缩小静态文件方面,您可能必须(也应该)在构build/部署时使用缩小工具。

MvcContrib.IncludeHandling适用于这种情况。 在这个例子中,我有一个样式集(string)的模型。 另外,如果我需要添加一个自定义的风格/ JS到页面,那么也可以做到这一点。 然后调用Html.RenderCss将所有样式/ js合并到一个文件中并将其缩小。

 <head> <% foreach (var styleSheet in Model.Styles) {%> <% Html.IncludeCss(styleSheet)); <% } %> <% Html.IncludeCss("~/Scripts/jquery.1.4.2.js")); <%= Html.RenderCss() %> </head> 

同样的方式为JavaScript。

 <% Html.IncludeJs("~/scripts/ConsoleLogger.js"); Html.IncludeJs("~/scripts/jquery.log.js"); Html.IncludeJs("~/Scripts/2010.1.416/jquery.validate.min.js"); Html.IncludeJs("~/Scripts/2010.1.416/telerik.calendar.min.js"); Html.IncludeJs("~/Scripts/2010.1.416/telerik.datepicker.js"); Html.IncludeJs("~/scripts/jquery.ui.datepicker-en-GB.js"); %> 

当这被渲染到客户端的输出看起来像这样(缩小组合1文件)

 <link rel='stylesheet' type='text/css' href='/include/css/-QdUg9EnX5mpI0e4aKAaOySIbno%40'/> 

该API还提供了一个debugging标志,当启用时不会缩小或组合脚本时设置非常有用。

几分钟之内,我就从Y的Yslow得分变成了B.(24脚本降到了2)…太棒了! 和一个40kbs的下降。

显而易见的缺点是服务器正在进行压缩。 我认为有一些选项可以将组合的脚本caching一段时间,这样可以很快地缓解这个问题。

正如其他人所build议的,你最好创build一个静态缩小版本。 或者,这里有一个可用于.NET的YUICompressor版本: http : //www.codeplex.com/YUICompressor

你可以使用MvcContrib.IncludeHandling。 它:

  • 支持CSS和JS
  • 结合到一个请求
  • Minifies
  • Gzip / Deflate压缩
  • 设置caching标题
  • 使用HTMLHelper扩展方法注册包括然后在运行时结合它们
  • 可通过IoC插入

在封面下,它使用YUICompressor。

我写了一些东西来自动处理这个。 它使用谷歌的闭包编译器。 你可以在这里阅读代码:

http://www.picnet.com.au/blogs/Guido/post/2009/12/10/Javascript-runtime-compilation-using-AspNet-and-Googles-Closure-Compiler.aspx

谢谢

圭多

我知道这是一个古老的问题,但是由于我正在进行一些缩小search,所以它首先出现了。 我会推荐使用Gruntjs, http: //gruntjs.com。 这是一个完整的网页制作工具。