Another comment was by Jeff Olson who said that he wanted better integration into an application via an executable which could scan a project and do replacements. He was advocating a similar approach to the one that I had already taken, but instead of specifying files manually, the tool needed to scan a project and compress and combine the needed files. While this is an interesting approach if you wanted a completely platform agnostic solution, but I decided that I would implement it in a bit different manner.
The first requirement that I thought was that it had to work in both ASP.NET and ASP.NET MVC. I also didn’t want to really have any setup or configuration. I also wanted it to output a physical file that I could simply pass a reference to. This way I could avoid having to do any manual caching and such. I just thought it would be easier to deal with. My only concern here revolves around the security of having a file actually written to disk inside of the website process. Some people could have a problem with this, and there could be issues around file locking, but nothing that couldn’t be coded around.
In order to use this, all you really need to do is create folder, throw the Bundler.Framework.dll in it, and then add a reference to the dll:
<%= new Bundle() .AddJs("/Scripts/jquery-1.3.2.js") .AddJs("/Scripts/MicrosoftAjax.debug.js") .RenderJs("/Scripts/Combined.js") %>
Notice that it appends the time that the combined file was generated as a querystring parameter. This is a little trick (which I borrowed from Nate Kohari’s Agile Zen) so that when the file is regenerated, the browser will download this file again instead of using the cached version. (This can be a problem if you have multiple servers all generating this file at potentially different times, and pointing to different files on disk, so I am going to have to rethink how this is implemented)
Another great thing is that if you are in debug mode, then it simply renders out the script tags as you would normally:
Very neat stuff.
So, how does it all work? Well, basically the Bundle class keeps a reference to every file it has output. So when it is called the first time it pulls all of the files and minifies and combines them, writes them out to the disk, and then renders the script tag. When the page is called a second time, the Bundle class simply checks to see if it has already rendered that file, and if it has, then it simply renders the script tag back to the client. If anything changes, just reset the application (this can easily be done by making a change in the web.config to update its date/time) and the Bundle class will lose the cached output for the script tag and then regenerate the combined file.
I’ve simply hacked this up in pretty short order this evening, and so you can go check out the source in GitHub. If you don’t use Git, then just click on the "Download Source" button and they will be happy to zip it up for you! Check it out, let me know if I’ve done anything horribly stupid, and I’d love to hear some feedback!