How can I automatically compress and minimize JavaScript files in an ASP.NET MVC app? How can I automatically compress and minimize JavaScript files in an ASP.NET MVC app? javascript javascript

How can I automatically compress and minimize JavaScript files in an ASP.NET MVC app?


I personally think that keeping the files separate during development is invaluable and that during production is when something like this counts. So I modified my deployment script in order to do that above.

I have a section that reads:

<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>

And in my master page file I use:

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><% } %>

The build script takes all the files in the section and combines them all together. Then I use YUI's minifier to get a minified version of the javascript. Because this is served by IIS, I would rather turn on compression in IIS to get gzip compression.**** Added ****My deployment script is an MSBuild script. I also use the excellent MSBuild community tasks (http://msbuildtasks.tigris.org/) to help deploy an application.

I'm not going to post my entire script file here, but here are some relevant lines to should demonstrate most of what it does.

The following section will run the build in asp.net compiler to copy the application over to the destination drive. (In a previous step I just run exec net use commands and map a network share drive).

<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>

After all of the solution projects are copied over I run this:

    <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>

That should be enough to get you started on automating deployment. I put all this stuff in a separate file called Aspnetdeploy.msbuild. I just msbuild /t:Target whenever I need to deploy to an environment.


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


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.