So I have an ASP.NET MVC app that references a number of javascript files in various places (in the site master and additional references in several views as well).
<Scott Hanselman recently blogged about combining and moving scripts to static files, basically using the ScriptManager with CompositeScript
references and a Path
attribute:
<asp:ScriptManager runat="server">
<CompositeScript path="http://www.example.com/1.js">
<Scripts>
<asp:ScriptReference />
<asp:ScriptReference />
<!-- etc. -->
</Scripts>
</CompositeScript>
</asp:ScriptManager>
In terms of minifying the static files, you probably have to (and should) use minifying tools at build/deployment time.
MvcContrib.IncludeHandling works well for this situation. In the example, I have a Model with a collection of styles (string). Also if I need to add a custom Style/JS to the page then can do that as well. Then calling Html.RenderCss combines all the styles/js together in one file and minifies it.
<head>
<% foreach (var styleSheet in Model.Styles) {%>
<% Html.IncludeCss(styleSheet));
<% } %>
<% Html.IncludeCss("~/Scripts/jquery.1.4.2.js"));
<%= Html.RenderCss() %>
</head>
Same way for 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");
%>
When this gets rendered to the client the output looks like this (minified combined 1 file)
<link rel='stylesheet' type='text/css' href='/include/css/-QdUg9EnX5mpI0e4aKAaOySIbno%40'/>
The API also offers a debug flag which when on doesn't minify or combine the scripts when set which is greatly useful.
In a matter of minutes I went from Yslow score of F to B. (24 scripts down to 2)... Awesome! And a drop of 40kbs.
Obvious downside is the server is doing the compression on the fly. I think there are options to cache the combined script for a defined period which would quickly alleviate this though.
Actually there is a much easier way using Web Deployment Projects (WDP). The WDP will manage the complexities of the aspnet__compiler and aspnet__merge tool. You can customize the process by a UI inside of Visual Studio.
As for the compressing the js files you can leave all of your js files in place and just compress these files during the build process. So in the WDP you would declare something like this:
<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>
This uses the JSCompress MSBuild task from the MSBuild Community Tasks which I think is based off of JSMin.
The idea is, leave all of your js files as they are (i.e. debuggable/human-readable). When you build your WDP it will first copy the js files to the OutputPath and then the CompressJavascript target is called to minimize the js files. This doesn't modify your original source files, just the ones in the output folder of the WDP project. Then you deploy the files in the WDPs output path, which includes the pre-compilied site. I covered this exact scenario in my book (link below my name).
You can also let the WDP handle creating the Virtual Directory as well, just check a checkbox and fill in the name of the virtual directory.
For some links on MSBuild:
Sayed Ibrahim Hashimi
My Book: Inside the Microsoft Build Engine : Using MSBuild and Team Foundation Build
I know this is an old question, but it came up first as I was doing some minification searches. I would recommend using Gruntjs, http://gruntjs.com. It is a complete web build tool.
As others have suggested, you'd be best off creating a static minified build. Alternatively, there's a version of YUICompressor available for .NET here: http://www.codeplex.com/YUICompressor
You could use MvcContrib.IncludeHandling. It:
Under the covers, it uses YUICompressor.