Conditional Compilation in JavaScript

A feature most people don’t seem to know about is conditional compilation in Internet Explorer web browsers.

For instance, there are times when you have the need to, in a fool-proof manner, find out if a web browser is Internet Explorer or what version of JScript (the JavaScript implementation in IE) is being used. Using object detection in JavaScript and general scripting in all honor, but there are cases where this doesn’t go all the way.

No matter how much we dislike to admit it, these types of need arise, and object detection has it flaws. Some web browsers offer the ability to mask themselves as another web browser, while others claim to support a certain feature through object detection but then fails in one way or another in the actual implementation. Enter conditional compilation.

Conditional compilation is a native solution available only in Internet Explorer, which offers web developers a way to find out a number of values of the current visiting web browser. To put it simple, it is conditional comments, which I’m sure a lot you use to include IE-specific stylesheets, but implemented in a JavaScript environment.

Code examples

To start out, you write a tweaked JavaScript comment:

/*@cc_on
	alert("Hello IE user (please, please switch)!");
@*/

As you can see, it is initialized with the /*@cc_on and closed with the @*/. More options include if and else-clauses as part of the comment:

/*@cc_on
	@if (@_win32)
		alert("You have 32-bit Windows");
	@else
		alert("You have IE but not 32-bit Windows");
	@end
@*/

There are ways to check web browser values such as if it is Windows, if it’s running a 32- or 64-bit system, the JScript version and build, and so on (complete list of conditional compilation variables).

Use this!

For future reference, if you want to be really really sure that your visitor is actually using Internet Explorer, I definitely recommend using conditional compilation to detect that. It can also offer you a solid way to do some necessary IE-specific code branching.

A simple way to check if the user is having the Internet Explorer web browser, suggested by Dean Edwards (lots of geeky comments here), is to do it like this:

var ie = /*@cc_on!@*/false;

Demo page

I’ve put together a small demo page of conditional compilation, whcih will only present the actual results in Internet Explorer.

A word of warning

As always with good things, there is one downside to this. Since conditional compilation takes place in a comment, if you use an approach to minify/clean out your code of comments before deploy, it will interpret this as any ol’ JavaScript comment, and remove it, resulting in weird and unexpected errors.

But fret not, it’s not as bad as you think. Unfortunately, JSMin removes conditional compilation comments, but I believe this is due to not having been updated in a while, and not up to speed with modern web development practices.

Using other tools such as YUI compressor or packer does indeed work fine with conditional compilation. However, both, as far as I can tell, fails to obfuscate variable names (if you have that option on) if you have code containing conditional compilation.

So, to conclude, I suggest using conditional compilation, but be aware of possible minification issues.

19 Comments

  • Grant Palin says:

    That's pretty cool. I can see that there are some cases where that sort of capability would be very useful.

  • Andreas says:

    Nice! Didn’t know about that. Too bad Nicolas Martin’s PHP-port of Dean’s packer does not keep them in :/

  • Martin says:

    I've previously used this to detect whether the current browser is IE or not:

    <code><!–[if lt IE 7]><script src="/js/ltie7.js" type="text/javascript"></script><![endif]–></code>

    Where ltie7.js contains the following:

    <code>var ltIE7 = true</code>

    I feel like I can trust this method more than checking Navigator properties. Alltough, looking at this code now, I'm not sure why i put the code in a new file instead of just writing it in the script block…

    The @cc_on-method is nice if you want to keep all your code in one place though.

  • Thank you for another nugget of wisdom Robert. Sometimes I feel that reading your blog is like going over stuff I've learned and forgotten again.

    So please keep the nuggets coming!

  • Use a specific code of a browser is not a good practice. I think we must insist on this point to recall whenever one gives tips and tricks like this.

    The best interface is simple and minimalist, but it is perform that the user expects.

    The best web code is the one that works with all browsers, because it is easier to maintain and it is accessible. Reduce to the minimum functional Javascript allows this.

  • Robert Nyman says:

    Grant,

    You're welcome. πŸ™‚

    Andreas,

    Ah, too bad. Wonder why he would break that implementation?

    Martin,

    Yes, it's all about cutting requests too. πŸ™‚

    Morgan,

    Thanks!

    philippe,

    There is a difference what we find to be best in theory, and what's best in real life. As mentioned in the post, using proper approaches such as object detection isn't fool-proof, hence the nedd for a solution like this (just as using conditional comments has almost become a de-facto standard to overcome IE-specific problems).

  • Often, the specific problems could be avoided by using simple solutions. Sometimes, we attack a concrete wall that could be circumvent.

    I prefer to talk about solutions proposed by the standards rather than specific solutions.

    Your ticket is interesting but I would have preferred that you start by saying that this tricks is to be used with caution in mind that the standards are the path to the side clear of force in order to protect young developers and show the way to the right direction πŸ™‚

  • Robert Nyman says:

    philippe,

    Well, I do hope people who read anything I have written, and with how this post is constructed too, do understand what my general stance is. πŸ™‚

  • pepelsbey says:

    Thanks for reminding this cool feature )

    So, now i have simple version targeting for emulating :hover pseudo-class on any elements by JS for IE6:

    <code>var ltIE7 = false

    /*@cc_on @if (@_jscript_version <= 5.6) ltIE7 = true @end @*/</code>

  • Robert Nyman says:

    pepelsbey,

    Absolutely, that's one usage. πŸ™‚

  • Robert,

    I have a version of JSMin that keeps in conditional comments. I modified the javascript version by Franck Marcia.

    What do you use to minify your code?

  • Robert Nyman says:

    Tanny,

    That's great! Thanks for letting me know!

    Personally, I use the YUI Compressor since it seems most effective and haven't broken any script (conditional compilation excepted, then).

  • Faruk Ate? says:

    I just thought I'd share here that the above code, combined with HTML-based IE Conditional Comments, allows you to reliably detect what rendering engine of IE you're dealing with.

    Now that IE8 is out and ships with both the IE7 and IE8 rendering engines, in a way that can no longer ever be detected by looking at the UserAgent string, this mechanic is rather valuable.

    I wrote it all down in a post on my own blog: IE8 and X-UA-Compatible part deux: solutions.

    Could be very useful for people πŸ™‚

  • Faruk Ate? says:

    Also, Rob! Shame on you for your system not supporting the special s in my name!

    ? ? ?

  • Robert Nyman says:

    Faruk,

    Dude, it's been a while! πŸ™‚

    Interesting, thanks for sharing – that situation os just so very hard to deal with.

    Sorry about the name, not really sure why that would happen. I have had UTF-8 for years, and your name has always worked before. I think I'll take the easy way out and blame the latest version of WordPress… πŸ˜›

  • […] of javascript if the user is using IE, or ignore them if not – I found out about them from Robert Nyman’s excellent blog entry on them – and whilst they may be great for places that develop heavily in IE, and support other […]

  • Felickz says:

    IE11 does not support conditional compilation by default. Please indicate this in your article!!!

    see demo here

Leave a Reply to Martin Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.