(This is part 3 of a series of posts on HTML5 from the point of view of a .NET developer)
One of the recurring questions when I tell someone that my new company's product is a "real" 100% HTML5 application and not just a fancified web site is about the libraries which we've chosen and why we've done so.
Whenever discussing libraries and frameworks for JavaScript applications, I think it's very important to point out that there are two very distinct classes of them: on one hand, you'll see a lot of general purpose libraries focused on smaller tasks. On the other hand, a number of prescriptive frameworks (for MVC, MVVM, storage, …) have been created, which recommend/support/suggest/mandate certain patterns, architectures and implementation paths.
General Purpose Libraries I'm using
In this post, I'd like to focus mainly on general purpose libraries. These are usually smaller libraries (apart from jQuery itself) which provide a distinct set of functionalities to be used in various kind of web application. A lot of them are very useful, no matter if you're creating a big single-page application, or a collection of more classic page-by-page web applications. The ones I generally use are also rather mature and of certain age (and therefore lower-risk).
The same thing unfortunately can't be said about the majority of prescriptive framework-style libraries. But that's definitely a topic for a future post.
jQuery and jQuery UI
jQuery shouldn't need much more than a simple mention. It's quite likely been the base for the majority of AJAX-enabled web sites for the last five years or so. Biggest difference to, say, Dojo Toolkit: no real component model. No modularization.
In general, that's not a big issue for me, but sometimes (especially when I'm writing native applications for iOS or Android, which might wrap a number of individual web views) the per-page initialization time might be critical. In this case, I tend to look towards zepto.js or similar low-impact jQuery derivatives instead.
less.js
CSS is fine. LESS is better. It gives you hierarchical CSS with support for constant and variable mixins. (The only thing I tend to miss is a built-in and cleaner handling for media queries.) less.js interprets LESS styles in the user's browser.
To reduce the risk of funny things happening over-the-air or with downlevel browsers, you could also instead compile LESS on the server side to give you regular CSS (there are a variety of compilers for the different development environments). Be aware though, the some of these compilers seem to be rather peculiar about their interpretation of certain LESS statements.
WARNING: Some mobile phone providers tend to transparently and automatically intercept HTTP requests over 2G, 3G or 4G links to optimize transfer times over high-latency communication links. This usually means that a proxy will cache your CSS and will even combine multiple CSS files into one to be sent directly in the HTML response. If you already use some kind of CSS and JS minification tool, this behavior is not nice, but it's still a fact of life you will have to deal with. One of the most obvious examples of this interference is the that it might render your LESS links invalid because the intercepting proxies tend to change the content-type specifier for the link which is used by the client-side LESS.js to find out which files need to be translated from LESS to CSS.
There are two possible workaround for this problem: for one, you could switch to HTTPS instead of HTTP as this pretty much guarantees that the HTML you send is the exact HTML the client receives. The other alternative is to send the following HTTP headers to convince your mobile operators to do the right thing (but unlike the HTTPS-solution, your mileage might vary, depending on whether the proxy honors these requests or not):
Cache-Control:no-cache
Cache-Control:no-store
Cache-Control:no-transform
Expires:-1
Pragma:no-cache
Handlebars.js
Today, handlebars.js is my preferred templating library. It supports markup extensions (helpers), so that you don't have to artificially create specific models which encapsulate display-only logic for individual views. I'm currently generally a big fan of template-only without too much databinding/MVVM-magic. (But that's a topic for a future post …)
jQuery BBQ (jquery.ba-bbq.js)
jQuery BBQ (Back Button and Query library) provides clean Hashchange-detection and emulation for browsers down to IE6. Work's perfectly and is a must-have staple for all single-page applications.
underscore.js
When I don't feel like writing for-loops to filter data, underscore.js is my preferred means for functional data manipulation. It's the closest you'll get (for now) to Linq-style collection code while remaining within JavaScript.
FullCalendar
FullCalendar is the calendar library for jQuery today.
jquery.fastclick.js
jQuery.fastclick.js is a library based on an article on Google's Mobile Developer Blog which illustrates how you can avoid the 300ms delay when clicking a button or link on most mobile touch-enable devices. It helps your application react instantaneously to more closely mimic the behavior of native applications.
Today, I'm using different fastclick-derivatives which are more specifically tailored for each particular project. (Mainly depending on whether or not the application is running solely in Phonegap-style wrappers so that it only has to support touch, but not click)
iso8601.js
iso8601.js is a library for parsing and writing dates from/to ISO8601 strings. As long as JSON doesn't define a standard date format, I'm using this library to take matters into my own hands.
We're also generally not transferring timezone information in the date/time itself but communicate this data out-of-band. (After all, it's no big fun if you switch to a server in a different timezone only to realize that now all your calendar-entries are off by a day)
Unit Testing
These were most of the general-purpose libraries I'm using on day-to-day basis. In the next post, I'll talk about the libraries and environments I'm currently using for unit testing and test-automation.
Your issue with mobile providers is one I ran into several years back. At the time, I was using a jQuery based client side template library that mandated templates in comment blocks in the page -- this was well before mustache, handlebars and the 20 other major template engines out there, and any set of standardized concepts on how to handle data-binding or models on the client. The aggressive proxies would strip out the comments, hence removing the templates. Since we had laptop users with aircards, it wasn't immediately obvious this was a mobile issue, until I was able to borrow one and do a little digging. Obviously template libraries have come a long way since then, but the DANGER DANGER point you make about is one to certainly always keep in the back of your mind, because it can really bite you!
Posted by: Ethan J. Brown | 04/24/2012 at 03:27 AM
Great post, thanks! Btw, Handlebars.js does not work in IE6
Posted by: Hajder | 05/03/2012 at 09:54 AM
Hajdar: If IE6 is still a topic for you, than there's quite likely a lot more which doesn't work for your target environment. It's really a pity that this browser is still around, but fortunately, we're seeing a lot of progress there and the instances in which I personally had to support IE6 are getting fewer and fewer.
Posted by: Ingo Rammer | 05/03/2012 at 10:02 AM
Ok thanks for the quick response, and I definitely agree with you, however with valuable clients that cannot switch it's a problem.
I also tried in IE7, IE8 and IE9 (!), it does not work. Any ideas? it works in Chrome, Opera, Safari & Firefox.
Thanks!
Posted by: Hajder | 05/03/2012 at 10:29 AM
Hadjer: Hmmm ... that's interesting. Just three weeks ago, I've deployed a larger app which needed to support a minimum of IE8 and Firefox 3.0.19 (both on WinXP SP2) based on Handlebars and it worked perfectly.
Posted by: Ingo Rammer | 05/03/2012 at 10:39 AM
Hadjer: I've just checked the history of Handlebars and its error log and it seems as if there has been an issue with IE7/8 which has been fixed about three months ago: https://github.com/wycats/handlebars.js/issues/85
Posted by: Ingo Rammer | 05/03/2012 at 10:41 AM
Ingo: I have checked my code because it seemed strange it didn't work in IE9. As a matter of fact, there was a duplicate element which caused a problem when displaying it on/off. Now it also works in IE6.
Posted by: Hajder | 05/03/2012 at 01:41 PM
Hadjer: Ahh ... that's fantastic. Thanks for taking the time to re-check this and share it!
Posted by: Ingo Rammer | 05/03/2012 at 01:55 PM
Ingo: what do you recommend for syntax highlighting handlebars files? Eclipse does not offer it by default.
Posted by: Hajder | 05/04/2012 at 10:04 AM
Hajder: My favorite IDE these days is definitely WebStorm (by Jetbrains). While it absolutely excels for all kinds of JavaScript editing, it provides also quite nice support for Handlebars and other "newer" web toolkits, like LESS.
Posted by: Ingo Rammer | 05/04/2012 at 10:49 AM