How to minimize and combine your JavaScript on Compile using Visual Studio

Last night I had the pleasure of presenting at the Orlando Dotnetnuke user group on this subject. This post is a follow up to that presentation.

I haven’t presented in a while and I have to admit I was a bit nervous, and to make matters worse the projector was not wanting to cooperate with me. Suddenly the room got really hot and I started sweating… I’m sure my sweating had nothing to do with the silence in the room while people waited for the technical problem to be resolved :)

It turned out that when I closed my machine at the office, it was connected to multiple monitors, so when I hibernated it remembered those settings and I could only get to projector to work as an extension of my desktop, like a second monitor.

Anyways… great learning opportunity, and I can’t wait to try it again. On to the technical stuff…

Goal:

I want the JavaScript file references in my pages to load the debug version of the JavaScript files when my visual studio solution is in debug mode. When Visual Studio is in release mode, I want a single compressed JavaScript file to be loaded.

Solution: (download)

Step 1: Download jsmin.exe from http://www.crockford.com/javascript/jsmin.html

Add it to your scripts directly in your project. You should not deploy this with your project, it is only needed during compile time to minimize and combine your JS files.

I use the following structure to store my javascript files:

captured_Image.png[4] 

Step 2: Add a post build command

Right click on your project, click properties. Select the compile tab and click on the build events on the bottom right of the screen.

captured_Image.png[6]

Enter the following command in the post-build event command line field:

 type “$(ProjectDir)content\js\libraries\*.debug.js” | “$(ProjectDir)content\js\libraries\jsmin” > “$(ProjectDir)content\js\libraries.min.js” 

captured_Image.png

This command does two things. First it looks for all the javascript files in your “content/js/libararies” directory ending with .debug.js and pipes it into the jsmin executable as one long string. Second it tells jsmin to output the compressed and combined JavaScript code to a single file content/js/libraries.min.js

Step 3: Add a debug flag

We need a way to figure out if we are in debug mode or release mode so to do this we are going to add a shared function to a helper library that will return true if in debug mode, and false if in release mode. In this function we use a compiler statement to compile “return true” when in debug mode and “return false” otherwise.

Public Shared Function IsInDebugMode() As Boolean
#If DEBUG Then
        Return True
#Else
        Return False
#End If
End Function

Step 4: Add a conditional statement to your pages

To your page you simply add this:

<% If jsmin.Helpers.IsInDebugMode Then%>
    <script src=”content/js/libraries/01-jquery-1.3.2.debug-vsdoc2.js” type=”text/javascript”></script>
    <script src=”content/js/libraries/01-jquery-1.3.2.debug.js” type=”text/javascript”></script>
    <script src=”content/js/libraries/02-jquery-ui-1.7.2.custom.debug.js” type=”text/javascript”></script>
    <script src=”content/js/libraries/03-jquery.autocomplete.debug.js” type=”text/javascript”></script>
    <script src=”content/js/libraries/04-jquery.blockUI.debug.js” type=”text/javascript”></script>
    <script src=”content/js/libraries/05-jquery.cluetip.debug.js” type=”text/javascript”></script>
    <script src=”content/js/libraries/06-jquery.form.debug.js” type=”text/javascript”></script>
    <script src=”content/js/libraries/07-jquery.validate.debug.js” type=”text/javascript”></script>
    <script src=”content/js/libraries/08-jquery.values.debug.js” type=”text/javascript”></script>
    <script src=”content/js/libraries/09-json2.debug.js” type=”text/javascript”></script>
    <script src=”content/js/libraries/10-app.debug.js” type=”text/javascript”></script>
<% Else%>
    <script src=”content/js/libraries.min.js” type=”text/javascript”></script>
<% End If%>

This tells your page that when IsInDebugMode is true, reference all the debug scripts, otherwise reference only the libraries.min.js script

Making it better

This is great, but I dislike having to add these conditional statements to every page, so created another simple helper function that goes through my libraries directory, grabs all my debug files and creates the html string to be included in the page. following the same rules, if in debug mode all the scripts, if in release mode only libraries.min.js

Public Shared Function JSReferences() As String
    Dim key = “JSReferences”
    Dim context = HttpContext.Current

    If context.Application(key) = “” Then
        If IsInDebugMode() Then
            Dim data = New StringBuilder
            For Each f In Directory.GetFiles(context.Request.MapPath(“~/content/js/libraries/”))
                f = f.ToLowerInvariant
                If Path.GetExtension(f).ToLowerInvariant = “.js” AndAlso _
                        f.EndsWith(“vsdoc2.js”) = False AndAlso _
                        f.EndsWith(“vsdoc.js”) = False Then
                    data.AppendLine(String.Format(“<script src=’{0}’ type=’text/javascript’></script>”, “content/js/libraries/” & Path.GetFileName(f)))
                End If
            Next
            context.Application.Add(key, data.ToString)
        Else

            context.Application.Add(key, “<script src=’content/js/libraries.min.js’ type=’text/javascript’></script>”)
        End If
    End If

    Return context.Application(key)
End Function

now I can replace the code in my html pages with this single line statement.

<%=jsmin.Helpers.JSReferences%>

That’s it. Enjoy!

Thanks to Dave Ward for the original idea http://encosia.com/2009/05/20/automatically-minify-and-combine-javascript-in-visual-studio/

jQuery intellisense does not work in Visual Studio

If you use jQuery with its vsdoc file in Visual Studio 2008, you might have noticed that sometimes when adding certain JavaScript files, like jQuery.UI, it knocks out your Visual Studio intellisense.

Here is a dead simple way to fix it.

1. First find the offending library that is messing with your jQuery IntelliSense. Do this by commenting one at a time and pressing Ctrl + Shift + J to force the JS IntelliSense engine to regen. Repeat until you don’t get a JS IntelliSense error (it should come up in the status bar, and as a warning in the errors window)

2. Replace the offending javascript file with something like this.

<script src=’<%= “../../Scripts/your_javascript_file.js” %>’ type=”text/javascript”>

When you do this, the Visual Studio JS intellisense engine, does not try to process  the javascript file, and you get your jQuery IntelliSense back.

Hope this helps. Cheers!

jQuery validation error inside the jQuery.UI.Dialog

This week I found a peculiar problem while trying to do validation inside a jQuery UI dialog box. Validation, although properly configured, would not happen, it would always show as valid.

This is the form, it is using the jquery.validation and the  jquery.ui.dialog components.

   1:  <form id="form1" runat="server">
   2:      <div id="dialog"></div>
   3:      <input type="button" id="load" value="Load Form" />
   4:  </form>
   5:  
   6:  <script type="text/javascript">
   7:  
   8:      $(function() {
   9:  
  10:          $('#form1').validate();
  11:  
  12:          $('#load').click(function() {
  13:              $.get('_form.aspx', function(data) {
  14:                  $('#dialog').html(data);
  15:                  $('#dialog').dialog();

  17:              });
  18:          });
  19:  
  20:      });
  21:  
  22:  
  23:  </script>

as you can see it is doing an ajax request to load the form. It then brings up the dialog box. Notice that the dialog div is inside the form therefore I’m expecting the loaded page to render within the form tag of the current page. This is the form that is loaded:

<input type="text" id="subject" class="required" />
<input type="submit" value="Submit Form" />

The problem is that the UI dialog will add a wrapper div and place it outside the form tag. It then moves the dialog div to be within it, effectively moving it outside the form. Therefore validation does not work as it is outside the form tag.

To fix this we write this simple line of code to reverse the process and move the dialog wrapper to be within the form tag.

$('#dialog').parent().appendTo($('#form1'));

It took me a little while to figure this out, and hopefully this will save you some time.

Cheers!

Happy Father’s Day!

I would like to wish all the fathers out there a very happy father’s day.

Mother’s day is the biggest rose selling day of the year, I wonder what is the biggest selling item for father’s day? Maybe tools, a new grill, etc. You see the pattern, we only get things to work harder! What’s up with that?

I imagine the geek Dad’s biggest selling category is tech, perhaps the new iPhone 3Gs, hint… hint…

Happy Father’s Day to all of us!

New project, new language, new MVC template, hi there again C#!

It has been a few months since my last C# project, and it is time to come back into the fold. For the last two projects, the client wanted VB.NET so we obliged them… you know, them being the clients and all, we kind of listen to them sometimes :P

I’m back to C# though and this time is going to be an MVC project. So whenever I’ve been away from a technology for a few months, I pickup my favorite book on it and go over the basics. I have to say that I’ve missed the style of C#, even though I’ve enjoyed the xml literals in VB…sigh…

So C# 3.0 In A Nutshell it is, what a great book. It covers C# from the basics to the common usage scenrios accross the different technologies (asp.net, LINQ, etc…) .

I’ve also started to create a new MVC template so I’m putting together all the usual suspects that will make my development life easier.

1. jQuery plugins and other useful JS libraries

2. JavaScript minify and combine. I then use jsmin to setup my automatic JS minify and combine through a VS post built event. Here is a great blog post from David Ward, who gets credit for the original idea.

3. Replace the existing template for this nice free CSS template from opendesign.org and we are half way there to creating a kick butt template.

I still have to setup xVal and a few other things, but that will be for the next post. For now, I’m ready to get started.

Welcome to my blog!

Hi, my name is Mitch Labrador and I’m a software developer living in Orlando, FL.

My primary technology focus is on Microsoft technologies, specifically ASP.NET, MVC, and SQL Server.

You can find me on Twitter@mitchlabrador and on LinkedIn.

I’m a member of the Orlando .NET User Group, the Orlando DotNetNuke User Group and the Tampa MVC User Group.

I co-founded Bigfoot Technologies with my partner Abe Sendros. We write line of business software for our clients, and also have a few commercial products that we sell using a SaaS model.

I plan on using this blog to discuss a range of subjects that are of interest to me from Technology to Politics (woot) . I’m a little late to the blogsphere :P but as they say, better late than never.

I hope you enjoy it!