codethinked (kōdthĭngked) adj. To be consumed by or obsessed with code.

Bundler Now Supports Named Bundles

I just pushed up a few minor changes to Bundler, my framework for combining and compressing JavaScript and Css, I also fixed a few bugs and cleaned things up a bit. The big thing I added was named bundles. I personally don't have a huge need for this feature currently, but I have worked on sites in the past where this sort of thing would come in handy. Let's take a quick look at how it works...

Support For Named Bundles

With Bundler the way it works by default, we just specified a bundle like this:

Bundle.Css()
    .Add("~/css/first.css")
    .Add("~/css/second.css")
    .Render("~/css/output.css");

The problem was that I was assuming that you could put this in a master page or somewhere that you would only have to specify this once. In my case this is mostly true. I have, however, had to work on sites in the past where it would be impossible to get a bundle of files into only one place. Because of this I decided to create what I call "Named" bundles. The idea would be that you would create a bundle in a single place (such as your global.asax file in app start) like this:

Bundle.Css()
    .Add("~/css/first.css")
    .Add("~/css/second.css")
    .AsNamed("Bundle1", "~/css/output.css");

And then whenever you need one of those named bundles rendered, you could just do it like this:

Bundle.Css().RenderNamed("Bundle1");

Simple enough. I'd still recommend that you try and refactor your site so that you really only need bundles in a single place, but if this is not possible, then bundles might be exactly what you need.

Support For The Css Media Attribute

One other small change I made was to support the Css media attribute. It just looks like this:

Bundle.Css()
    .Add("~/css/first.css")
    .Add("~/css/second.css")
    .WithMedia("screen")
    .Render("~/css/output.css");

I hope you get a chance to go check it out by heading over to the Bundler download page on GitHub.

Comments

Claus

After up grading to 0.4, I keep getting an error on my javascript bundle code that an item with the same key has already been added. I'm adding only two (different) JavaScript files, I'm in Debug mode in VS2010.
Any ideas?

Claus

March 22. 2010 04:27

United States
pingback

Pingback from blog.cwa.me.uk

The Morning Brew - Chris Alcock  » The Morning Brew #564

blog.cwa.me.uk

March 22. 2010 04:44

Viktor Bergman

When using this code:
<%Bundle.Css()
    .Add("~/css/site.base.css")
    .Add("~/css/site.headers.css")
    .AsNamed("Bundle1", "~/css/output.css"); %>
<%Response.Write(Bundle.Css().RenderNamed("Bundle1"));%>

Bundler does not render output.css, instead it renders:

<link rel="stylesheet" type="text/css"  href="/css/site.base.css" />
<link rel="stylesheet" type="text/css"  href="/css/site.headers.css" />

Should'nt it render:
<link rel="stylesheet" type="text/css"  href="/css/output.css" />  ?

Viktor Bergman

March 22. 2010 05:48

Sweden
Justin Etheredge

@claus I think I might know what I did. I'll look into it soon.

@viktor Do you have debugging turned on in your web.config? If so, it renders the files normally to allow for easier debugging.

Justin Etheredge

March 22. 2010 07:51

United States
Justin Etheredge

@claus I just pushed out a new version, let me know if that fixed your issue.

Justin Etheredge

March 22. 2010 08:07

United States
Claus

Justin - looks like you done fixed it! I'll let you know how it holds up...Thanks!

Claus

March 23. 2010 03:03

United States
Claus

Justin - just also tested in Release mode on the server and get this exception whether I use virtual (~/scripts) or regular (../../scripts). Works in debug mode. Any ideas? Thanks!

[HttpException (0x80004005): Cannot use a leading .. to exit above the top directory.]
   System.Web.Util.UrlPath.ReduceVirtualPath(String path) +11359135
   System.Web.Util.UrlPath.Reduce(String path) +171
   System.Web.VirtualPath.Combine(VirtualPath relativePath) +214
   System.Web.HttpRequest.MapPath(VirtualPath virtualPath, VirtualPath baseVirtualDir, Boolean allowCrossAppMapping) +204
   System.Web.HttpServerUtility.MapPath(String path) +252
   Bundler.Framework.CssBundle.Render(String renderTo, String key) +246

Claus

March 23. 2010 03:12

United States
Justin Etheredge

@Claus I can reproduce the error, but only if I do what it says, which is to use a ".." to back up past the top level of the website. What do your script references look like?

Justin Etheredge

March 23. 2010 07:30

United States
Claus

Justin, looks like the problem was that some of my .Add calls had files with version numbers like so:

.Add("~/client/scripts/cw.mediaplayer.js?v=1")

Took them out, now it all works, thanks!

Claus

March 24. 2010 12:51

United States
Justin Etheredge

@Claus Hmm, I would think that this should still work though. Must be a problem mapping that url with the query string parameter to a file on disk. Could you log that as a bug in GitHub.

Justin Etheredge

March 24. 2010 13:19

United States
Luke Lowrey

Looks really good mate.

When does the bundling actually take place?
On page load, application start or as a build step?

Luke Lowrey

March 25. 2010 21:24

Australia
Justin Etheredge

@Luke It takes place the first time the page is loaded, after that the file is created and not re-compressed over and over.

Justin Etheredge

March 25. 2010 22:52

United States
Miguel

Hello,

I am using TinyMCE on a MVC project and on the JS code that initiates the TinyMCE code I need to specify the location of a CSS file.

I am using Bundler with AsNamed instead of Render to compress the CSS file and give it the key "TinyMCE".

To reference that file in my JS code should I just add the url or maybe some other way?

What about the "r=..." part?

Thanks,
Miguel

Miguel

March 31. 2010 19:43

United States
trackback

Social comments and analytics for this post

This post was mentioned on Twitter by w3max: @alex_gyoshev @karlseguin @JustinEtheredge I was not taking side by retweeting karl's message. I dig this approach too http://bit.ly/95CHRE

uberVU - social comments

April 3. 2010 03:25

willabee

In your original command line version, you had the option to include a text file in a directory of files and load order, plus an option to request from a URL. Is there any chance you could re-enable these options in the next version?

willabee

April 30. 2010 07:11

United Kingdom
Justin Etheredge

@willabee I was attempting to accomplish something similar with the named bundles, but that still requires you to make changes in the code. The named bundles let you specify your includes in one place and then render them out by just specifying a name.

The folder option would still require you to have to add a new file, include it in the "ordering" file, and then you would still have to go into your project to use the javascript. Is there some big advantage that I am missing here? I'm not saying I won't add it back in, but I want to make sure that there is some key advantage in doing it this way.

Justin Etheredge

April 30. 2010 08:42

United States
willabee

I had not seen the named bundles option and I agree that it makes the ordering file redundant.

The only thing missing is CSS highlighting in VS2010 for files with a .less extension.

I downloaded CSS Is Less from visualstudiogallery.msdn.microsoft.com/.../dd5635b0-3c70-484f-abcb-cbdcabaa9923 to fix this.

Thanks for a great solution.

willabee

May 2. 2010 07:46

United Kingdom
Gene

First, thanks for this, it is very useful and I like the simplicity. However, I'm also having an issue with the debug line, such that this works once the project gets to production, but does not work in release mode on my dev machine.

In a  VS 2010 project, where the web.config file is updated from the web.debug.config and web.release.config files, iun this case

compilation debug="false"  

is replaced during a release build from the web.release.config file, using

<compilation xdt:Transform="RemoveAttributes(debug)" />

In this situation, (only for a build on my dev machine in release mode, when using publish to push a release version of the project to another a production directory it works properly), née Bundler outputs all the css files as if still in debug mode.

If I manually edit the web.config file to

compilation debug="release"

Bundler outputs the proper combined css file (I have not tested if the behavior is the same with javascript, but I assume so).

<link rel="stylesheet" type="text/css"  href="/content/css/combined.css?r=DDEDD872E958CDE0A10C3BE655F648A7" />

If there is no easy fix, then just a note to explain would save some time debugging.

Gene

May 7. 2010 13:40

United States
Justin Etheredge

@gene I'm not sure why that is happening, I'll have to look into it. Thanks!

Justin Etheredge

May 7. 2010 13:51

United States
Gene

I think the behavior is explicable in that the web.release.config file doesn't remove the compilation debug attribute just by switching to a 'release' build -- you need to publish the project in some form. Otherwise, even in release mode the web.config stays as debug="true".

Does Bundler rely on the web.config compilation debug attribute? Or does it look at whichever project/solution file visual studio sets the build configuration (as displayed in the project | properties | build |  configuration | Active(Release).

If web.config then to get this to work on an inplace release compile, you would have manually set compilation debug="false" in web.config.

Again, works in production, so perfectly usable, only confusing when doing a release build on my machine and expecting to see the nicely combined css file.

Gene

May 7. 2010 16:45

United States
Chris

Justin, awesome work dude. I got it working in about 10 minutes. Quick question - how would I use conditional comment css and js includes inside the Bundle.Css and Bundle.Js calls? Thanks again for your work.

Chris

May 14. 2010 01:38

United States
Justin Etheredge

@Chris I think you could use it in conditional comments just fine, but they would have to be a separate bundle. Just put the comment tags around the output tags from SquishIt/Bundler.

Justin Etheredge

May 15. 2010 08:31

United States

Add Comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading