MiniMe–opinionated JavaScript and CSS bundling

by dotnetnerd 6. July 2011 20:03

Why MiniMe?

For a while I have been using SquishIt to minify, bundle and version JavaScript and CSS files – and to a large extent it did a good job. However on a number of occations I ran into a group of scenarios where it just didn’t quite do enough for what I wanted. So when I was starting a new project and ran into the same issues again, I decided to take a look at making my own.

The basic idea behind MiniMe is that it should make it easy to bundle JavaScript and CSS files across masterpages, usercontrols etc. with the option to control how they are sorted, and end up with one file that is minified and versioned. It should also be easy to introduce into an existing project, with a minimal amount of refactoring, and lastly it should be easy to adhere to best practices and inject the script tag at the very bottom of the html page.

These are the requirements that I run into again and again, so I wanted a tool that did exactly that.

Getting started

To make it as easy as possible I made a nuget package, so all you need to get off the ground is to search for MiniMe in the package manager and hit install.

Building a complete file

Now you have access to the classes MiniJavaScriptBuilder and MiniStyleSheetBuilder, that can be used to build either a JavaScript or CSS file. The approach is similar, so from how on I will just show the JavaScript case. Using either one you can build a collection of files by calling Add or AddToRequest, which takes a path to the file you wish to add. The difference is that Add is local to the instance of the builder, where the ToRequest version is stored for the request across any number of builders. Both methods return the builder instance, so calls to Add/AddToRequest can be chained.

@{ new MiniMe.MiniJavaScriptBuilder()
    .AddToRequest(Url.Content("/scripts/myFirstScriptFile.js"))
    .AddToRequest(Url.Content("/scripts/mySecondScriptFile.js"), 1)         
    }

When using AddToRequest you can optionally pass an index as a second parameter. Files with a lower index are included before those with a higher index – allowing files that are added from usercontrols to run after those added in the masterpage.

Manually rendering a combined file

When all your files have been added you can call either Render or RenderForRequest, which will behave differently depending on if you have turned debug on in web.config or not. If you are in debugmode there is simply rendered a reference to each file, allowing you to debug like you are used to. If you are NOT in debugmode the files that were added will be combined and saved to the path you pass to the method. Writing a # as part of the path will enable versioning, so the # is replaced by a hashvalue of the filecontent. Versioning will make sure the filename changes when any of the files are changed, so caching does not prevent your users from getting any changes that you have made.

@{ MvcHtmlString.Create(new MiniMe.MiniJavaScriptBuilder()
.AddToRequest(Url.Content("/scripts/myFirstScriptFile.js"))
.AddToRequest(Url.Content("/scripts/mySecondScriptFile.js"), 1)
.RenderForRequest(Url.Content("~/Scripts/Site_#.min.js")))
}

Automatically injecting a combined file

Working with complex layouts can be a pain, because you have to take into account the order the usercontrols are rendered, and you will have duplication of code to render the files. To solve this MiniMe comes with an HttpHandler that will handle the rendering for you. This means that files that are added to the request, will be bundled, the combined JavaScript is referenced from the very bottom of the page and the Stylesheet is referenced from the header. All you have to do is add the HttpModule.

<system.webServer>
    <modules>
        <add name="MiniHttpModule" type="MiniMe.MiniHttpModule, MiniMe"/>

By default the HttpModule renderes the files to “/Scripts/Site_#.min.js” and “/Content/Site_#.css” – this can be overwritten using appSettings

<appSettings>
    <add key="MiniJsRelativePath" value="/Scripts/OtherSite_#.min.js"/>
    <add key="MiniCssRelativePath" value="/Content/OtherSite_#.min.css"/>

Create .min.js versions of all JavaScript files

In some cases you might want to have MiniMe generate .min.js versions for any files that have not yet been minified. This will also give you a slight performance boost, because MiniMe will not have to do the minification on the fly when files are combined. It is important to note that MiniMe will only make minified versions when no minified version already exist. Personally my preference is to do it when not running in debugmode, because then I won’t have to delete the minified versions when I make chances, in order for MiniMe to generate new ones.

if (!HttpContext.Current.IsDebuggingEnabled) new MiniGenerator().EnsureMiniVersions("/Scripts");

Go to the source to gain more insight or contribute

MiniMe is hosted on bitbucket, so if you wish to see how it works, or if you want to contribute please don’t hesitate. The first version was focused around the features I felt were missing, but there are undoubtedly other scenarios that can provide value.

Mama said knock you out!

by dotnetnerd 20. May 2011 13:35

In my last post I looked at how WCF Web API plays well with JQuery Templates. A former colleague of mine questioned if it could be used in all scenarios. This is a rather broad question, but I do think it can be used for most of your templating needs.  So in this post I will give an example of what can be done just with templates – and then I will take a look at KnockoutJS to make my templating scenario even sweeter.

More...

Web API playing well with JQuery Templates

by DotNetNerd 1. May 2011 21:38

Since my last blogpost about Web API Glenn Block appeared on Hanselminutes so it seems to be hot stuff at the moment. Having already written part of this blogpost, as it was actually part of the last post before I decided to break it in half, it seems a good time to finish it and get it out there. So building on my last post I will also take a look at how Web API plays along with JQuery and the new JQuery templates.

More...

Web API – for HTTP what MVC is for HTML

by dotnetnerd 25. April 2011 14:14

Over the last couple of weeks I have been looking a bit at the WCF Web API which I think is looking very promising. Web API is one of Microsofts newer open source projects,  aiming at providing http based services on top of WCF - while providing an easy to use API that give developers full control. In a way this makes me think of MVC, which has given control of the markup back to the developers, just like Web API is trying to do for http. Already loving what MVC has done for me, this makes me very positivt about the approach right off the bat.

RESTful services seem to be all the rage these days, which made me look at some of the choices we have as developers for doing REST. This was really my first look at Web API, so with it being one of the more exciting news at MIX11, it was only natural to take a deeper look.

20667-650x203crop0

More...

Yearning for some learning?

by DotNetNerd 1. April 2011 19:57

A piece of advise that is often given to developers who want to keep improving, is to learn a new programming language every year. I mostly think it holds true if you try to learn a new paradigme – because just learning new syntax won’t really get you anywhere.

Koans

One way of learning a new language is of course to buy a book or two, and start reading and doing some samples and small applications. Another way of going about it is to try some of the koans, interactive interpreters and introductory guides that can be found online.

1000_jaws_koan

More...

I need a REST

by dotnetnerd 9. March 2011 18:37

One might think that the title of this blogpost is due to the fact that this summer I will be turning 30.
However it is actually a task I have been looking into, that could also be phrased as: I wish to build a REST based service, what are my options? With REST gaining in popularity I think this a question that a number of developers are asking themselves these days.

First of all what is REST? REST is about staying true to the HTTP protocol, and using it to communicate between a client and a server - as opposed to SOAP. To parafrase from Wikipedia being RESTful is about using URIs, HTTP verbs and mediatypes as the means to communicate using a traditional request/response model.

http

More...

Tags: , ,

Gettin’ git-ty with it

by DotNetNerd 3. March 2011 16:28

For some time I have heard good things about git and mercurial, but just never got around to really looking at it. So when I had last week off I finally got around to doing more than just cloning a repository from github or bitbucket. Basically what I needed was some easy way of doing source control for my pet projects, so either would no doubt get the job done.

My focus ended up being mostly on git simply simply because I often run into github when I read about open source projects that I find interesting. Another thing I had in the back of my head was that I could take a look at appharbor - which I hear about a lot on twitter. That being said I did read the Hg Init tutorial, just to get a feel of the differences between the two. As it turnes out they are very similar, so it will probably be the integration with github, bitbucket, heroku and so on that will decide for me in each case.

More...

Let me be Frank, I really like Sinatra

by dotnetnerd 9. February 2011 13:36

Lately I have heard quite a few people mention the Sinatra framework, which is a very light-weight webframework for Ruby. Already being fond of Ruby I decided to take a look at Sinatra, so I could see what all the fuss was about.

Right off the bat I decided to install Ruby instead of going with IronRuby like I had done so far. Sadly I am not feeling too secure about the future of IronRuby, since Microsoft stopped investing in it - but of course I really hope that it will continue to go foreward as open source. Because of this insecurity and because of basic curiosity I decided to to “pure Ruby”. After all getting started is just running the installer you can download from ruby-lang.

Sinatra

More...

Tags: , , ,

Silverlight – One ring to bring them all and in the darkness bind them

by DotNetNerd 12. January 2011 16:01

Lately I have had the chance to work with Silverlight, which suits me just fine since I am looking to get my hands on a HTC Mozart, and start building some apps. I was already in the process of reading Silverlight 4 in Action, so it all seems to come together at the moment.

Diving in I have been looking at bindings, which in turn made me look at the MVVM pattern and in the end Caliburn Micro. Anyway, I am getting ahead of myself, because what I want to write about today is how bindings work in Silverlight.

One ring to rule them all

More...

Tags:

Battle of the ORM’s – Persistence

by DotNetNerd 30. December 2010 17:41

The last thing I will compare in this round of Battle of the ORM’s is how NHibernate and the Entity Framework handle persistence. So first of all I want to vent one of my pet peeves, which is the myth of persistence ignorence.

Persistence ignorence is a term used to describe a persistence mecanism that does not contaminate the domain model and hence the business logic. This means that the model can be ignorent of how it is stored and not contain detals about the datastore. I think this a very important design goal to strive for, however actually obtaining true ignorence is a myth and something no ORM is even close to achieving.

More...

Who am I?

My name is Christian Holm Diget, and I work as an independent consultant, in Denmark, where I write code, give advice on architecture and help with training. On the side I get to do a bit of speaking and help with miscellaneous community events.

Some of my primary focus areas are code quality, programming languages and using new technologies to provide value.

Microsoft Certified Professional Developer

Microsoft Most Valuable Professional

Month List