Tag Archives: JavaScript

Functional Testing for the Lazy Developer with CasperJS

Looking for a functional testing framework to test your web application front-to-back? Not sure whether to focus on Integration or Unit Tests? Casper JS may well be the right tool for the job. Learn more about front-end testing and how you can put it to work for you by checking out my blog post over on Help Scout's blog.

Introducing Marionette-Require-Boilerplate for Your Single Page Application

Marionette-Require-Boilerplate (MRB) is a simple boilerplate I created to help get Single Page Applications off the ground with a small starter project. It incorporates a number of great tools and best practices to save time in the early stages of a project.

MRB integrates such cutting edge libraries as Backbone, Marionette, Require, Grunt, Jasmine, Bootstrap and jQuery Mobile, among others. These libraries work together to help you start your project off with a rock-solid foundation, with a powerful module system, composite architecture, simple build process, and unit tests. Marionette-Require-Boilerplate is part of the BoilerplateMVC suite, which includes standouts like Backbone-Require-Boilerplate, the inspiration and basis for MRB. Stay tuned for more from the BoilerplateMVC team!

The GitHub repo has more extensive documentation, but in this post I’d like to introduce some of the underlying technologies and explain what makes MRB a great place to start for your SPA.

Marionette

Marionette is a framework that sits on top of Backbone and provides a composite architecture and a set of tools to help you solve some of the most common problems in Backbone applications, including nested views and layouts, memory management and cleanup of zombie views, and event-driven architecture. Backbone is a fantastic library and provides many useful pieces, but its great strength — lightweight flexibility — is also its great weakness. It is not a framework and leaves you to figure out some basic functions, like how best to create and remove views, or how to nest views within each other.

If you are not confident in your ability to competently architect a Backbone JS application, or you’re just looking to save time, then Marionette is the tool for you. Read more about what it has to offer in the Marionette chapter of Addy Osmani’s Backbone Fundamentals e-book.

Require

RequireJS is the most popular implementation of the Asynchronous Module Definition (AMD) spec. It provides a powerful, flexible and consistent way to organize your application into separate modules with clearly defined dependencies. It allows you to load these modules as separate files asynchronously in your code, or use the r.js optimizer to load all of your modules in a single, minified JS file for production builds.

Note: Marionette has a concept of Module that is very different from the RequireJS “Module” concept. Do not confuse the two. In Require, a module is simply a unit of code that is run once and returns a function or object of some kind for use in other modules. In Marionette, a Module is essentially a section of your application that can be started or stopped, serving as a coarse grain method of organizing your code. It would be possible to define a Marionette Module in a Require Module if you like, but your head might explode.

Bootstrap and jQuery Mobile

Twitter Bootstrap is a leading front-end UI framework for building rich web applications. It includes a large set of CSS classes and jQuery widgets that you can add to your markup to transform it into beautiful, sleek and customizable UI elements. It is an ubiquitous framework — popular because it helps developers who lack certain design skills to easily crank out clean, elegant UIs with minimal effort and non-invasive code and CSS. jQuery Mobile is a leading UI framework for mobile applications that builds on jQuery UI and brings a number of mobile-friendly widgets and controls to the table.

Mobile vs Desktop

MRB uses a scheme (borrowed from Backbone-Require-Boilerplate) that detects the user’s browser and loads either Bootstrap or jQuery Mobile accordingly. It also loads either the Desktop Marionette Controller or the Mobile Marionette Controller. In Marionette, a Controller handles a Router’s routes, and is used to instantiate Models and Views and show them in appropriate Regions or Layouts.

In MRB, the Mobile/Desktop Controllers load Views which work with either jQuery Mobile or Bootstrap (for instance, MobileController loads a MobileHeaderView, while DesktopController loads a DesktopHeaderView). This is our strategy for differentiating behavior and UI elements for mobile or desktop. This is just my strategy, and it may or may not work well for you, so take it or leave it. If you don’t want to worry about the mobile/desktop dichotomy up front, you might consider checking out Marionette-Require-Boilerplate-Lite, which eschews this division and skips jQuery Mobile in favor of a purely Bootstrap approach. Whichever you prefer.

Grunt

Grunt is a first-rate build tool built on Node which allows you to run any number of compatible plugins. In MRB, we use Grunt to execute our RequireJS Optimization, minify our JavaScript and CSS, and run JSHint to detect bugs in our code.

Jasmine

MRB uses Jasmine to execute and manage unit tests. Jasmine’s syntax is very readable and makes it an attractive choice for unit tests.

Handlebars

Handlebars is our templating engine of choice. It offers a clean, friendly syntax that discourages excessive logic in your views, and is a popular choice these days over EJS-style templating options like Underscore’s _.template(). In MRB, we use the require-handlebars-plugin to automatically load our templates as AMD modules, pre-compiled (read: big performance boost) and with custom helper methods and i18n support.

Node HTTP Server

MRB runs a simple Node HttpServer on port 8001. This is not necessary, but since Grunt and the RequireJS optimizer both run on Node, it is a reasonable assumption that the user will have it installed. If you don’t want to run MRB on Node, you can just as easily point a simple Apache web server at the public/ directory in the project. A web server is required; using the plain file system won’t work because of RequireJS’s dynamic loading of resources.

Best Tools plus Best Practices

With Marionette-Require-Boilerplate, I have attempted to bring together a collection of great tools and best practices to help web applications get started quickly and with a firm footing. I hope you find it as useful as I have. I’d love to hear your feedback, so follow me on GitHub or hit me up on Twitter!

On Templating in Backbone

I recently saw a post on Hacker News about adding custom extensions to Handlebars which allow you to call methods on the data that is passed to your Handlebars template. Before I had a chance, someone astutely pointed out that Handlebars is designed for logicless view rendering, but that other templating solutions do offer the ability to include real logic in your templates.

This got me thinking, and I thought I’d share what has been my approach to templating in my own Backbone apps.

Handlebars – beautiful syntax & logic made difficult

Handlebars is designed to be semantically pleasing. It’s hard to beat in terms of syntax:

<h1>{{title}}</h1>
<ul>
  {{#each people}}
  <li>{{this}}</li>
  {{/each}}
</ul>

When it comes to logic though, you are limited to a few basic built-in helpers or are forced to add your own custom helpers. For instance, if you want to check for whether a description attribute is truthy, you can do this:

    {{#if description}}
       <span>{{description}}</span>
    {{/if}}

But if you are looking to check whether an attribute matches a given value, you are out of luck.

Does not work

    {{#if age >= 21}}
        <h1>Drink up!</h1>
    {{/if}}

This is a reasonable thing to wish to do, but to do this in Handlebars would require you to write your own custom extension, like so:

Helper method
    Handlebars.registerHelper('isLegal', function(val, options) {
       if ( val >= 21 ) {
          return options.fn();    
       } else {
          return options.inverse();
       }
    });
Template
    {{#if isLegal}}
       <h1>Drink up!</h1>
    {{else}}
       <h1>Bummer</h1>
    {{/if}}

There is something to be said for forcing you to work hard to implement custom logic in your templates, but we programmers are pragmatic and sometimes you just want something done fast. In these cases, I like to fall back on a much uglier, more powerful templating solution: _.template()

Underscore – ugly syntax & logic made easy

Underscore templates won’t win any awards for elegance. While they may appeal to some Java jockeys coming from JSPs, for most of us it’s a no-brainer which syntax is easier to use.

    <h1><%= title %></h1>
    <ul>
      <% for (var i = 0; i < people.length; i++ ) { %>
      <li><%= people[i] %></li>
      <% } %>
    </ul>

That being, said, logic is easy and you can put as much of it as you like in your Underscore templates!

    <% if ( age >= 21 ) { %>
        <h1>Drink up!</h1>
    <% } %>

I choose… both!

With Backbone, I think people feel like they have to choose between the two ways of templating, each with its own advantages and drawbacks. But I think this is really a false choice – each excels in its own way and with Backbone it’s easy to choose both!

What I have found to be best is a Handlebars-first, Underscore-if-needed approach. You can’t beat Handlebars for syntax, and your project ought to be structured in such a way that your templates don’t require much logic anyway. But in those cases where you really do need something more powerful, there is no harm done in falling back on Underscore. In fact, since Backbone itself depends on Underscore already, it’s already right there waiting for you to use!

Here’s an example of 2 views, one which renders with Handlebars, and one with Underscore:

HandlebarsView
 var HandlebarsView = Backbone.View.extend({
        template: _.template(handlebarsTemplate);
        model: new Backbone.Model({
            title: "Famous Authors",
            authors: ["Hemingway","Hawthorne","Orwell"]
        }),
        
        render: function() {
            this.$el.html(this.template(this.model.toJSON()))
        }
    });
Handlebars Template
    <h1>{{title}}</h1>
    <ul>
      {{#each people}}
      <li>{{this}}</li>
      {{/each}}
    </ul>
UnderscoreView
var UnderscoreView = Backbone.View.extend({
        template: Handlebars.compile(underscoreTemplate);
        model: new Backbone.Model({
            age: 23,
            legalMessage:"Drink up!"
        }),
        
        render: function() {
            this.$el.html(this.template(this.model.toJSON()))
        }
    });
Underscore Template
    <!--Underscore Template-->
    <% if ( age >= 21 ) { %>
        <h1>Drink up!</h1>
    <% } %>

Here we see how little effort is required to swap out your templating engine (something of a contrived example, I know). This can be done on a View-by-View basis and IMHO offers the best of both worlds. I’d love to hear your thoughts, so leave a comment or hit me up on Twitter.

Modularization in TypeScript

UPDATE 2: The 0.9 release of TypeScript added support for CommonJS-style `module.exports = {}`, allowing you to export a class! This makes exporting/importing very, very much easier, and obviates the need for some of the more convoluted stuff at the end of this post.

UPDATE: Check out the new github project that accompanies this post:typescript-modularizatino-demo

In my last post, I introduced TypeScript, Microsoft’s new offering which layers static typing on top of JavaScript. Today I’d like to go further and discuss modularization and code organization.
TypeScript has the ability to take advantage of a pair of JavaScript modularization standards: CommonJS and Asynchronous Module Definition (AMD). These capabilities allow for projects to be organized in a manner similar to what a “mature,” traditional server-side OO language provides. This is particularly useful for the most likely candidates for TypeScript – large Web Applications.

Although TypeScript’s modularization is powerful, it requires some background knowledge of CommonJS and AMD, and has its pitfalls. I hope in this post to be able to provide some of that background knowledge and provide some helpful pointers in organizing your TypeScript project in a modular fashion. Particular attention is paid to the topic of importing plain JavaScript files in your TypeScript code.

On the State of Modularization in JavaScript

Organizing scripts in JavaScript-based web apps has historically been a thorny issue. With no native, built-in system for modularizing code into packages, applications tended to quickly devolve into Script Tag Hell – dependencies being resolved by remembering to put this script tag before that one, but not before the other! Add to this the difficulty of preventing pollution of the global namespace and you have strong incentives to structure your application in as few files as possible.
Over time, these factors tended to act as a gravitational force, pulling your code closer and closer together, until the entire application collapsed under its own weight into a single black hole of a JavaScript file before all but the most senior of developers cowered in fear.
Okay, so that’s a bit of a dramatization. But the fact is that organizing JavaScript projects by hand was extremely difficult, and often was simply left undone. Fortunately, a pair of specifications was created to address just this problem!

CommonJS and AMD

CommonJS and AMD provide mechanisms for loading JavaScript files as separate modules, giving you the power of organization needed in both server- and client-side JavaScript applications.

The primary differences between CommonJS and AMD are as follows:

  • CommonJS is synchronous in nature; AMD loads files asynchronously
  • CommonJS is primarily used on the server in conjunction with node; AMD is most useful in the browser and its most popular implementation is RequireJS.

If you’re looking for more info, a good overview of the two can be found here (note that you must use the left/right arrow keys to navigate between slides). So, let’s get started with a basic example of what the syntax for each of these looks like.

CommonJS

CommonJS uses three “magic” keywords – require, module, and exports. Here’s what a simple example of a CommonJS Module file might look like:

greeter.js

function sayHello(name) {
   alert("Hello, " + name);
}
exports.sayHello = sayHello;

Here we use the magical exports variable to hang our sayHello function off of. To use this module in another file, we use require.

app.js

var greeter = require("greeter");
greeter.sayHello("Dave");

Simple enough, right? Only methods or variables which are attached to exports are available outside the file. At this time, note that both CommonJS and AMD modules follow the Singleton pattern – when you include a module the first time, the code in that file runs. The second time you include it, you get a reference to the object which was produced the first time.

The last keyword CommonJS uses is the module keyword, which provides some additional capabilities (read about them here), one of which is a module.exports property. This property is initially the same as the exports property and can be used to hang off public methods and variables, but it also allows you to manually define exactly what object gets returned when the current module is required. For instance:

greeter.js

function sayHello(name) {
   alert("Hello, " + name);
}
exports.sayHello = sayHello;
module.exports = "Hello World";

app.js

var greeter = require("greeter");
alert(greeter); //alerts "Hello World"

Here we see that although we set exports.sayHello to a function, we overrode the entire returned module by setting module.exports to the string “Hello World.”

AMD

Let’s now turn to AMD. AMD’s special keywords are define and require (it works differently than the require in CommonJS so keep that in mind). define is used to define new modules, and require is used to load them. Keeping in mind that the “A” stands for “Asynchronous,” we are not surprised that AMD’s syntax involves callback functions.

greeter.js

define([/*dependencies go here*/], function (/*and get mapped to variables here*/) {
   return {
      sayHello: function(name) {
         alert("Hello, " + name);
      }
   }
});

And to load this module, we do so either in another define call, or dynamically with Require.

app.js

//define an "app" module
define(["greeter"], function (greeter) {
   var app = {
      initialize: function() {
         greeter.sayHello("Dave");
      }
   }
   return app;
});

-or-

function initialize() {
//dynamically load "greeter" without defining another module
   require(["greeter"], function (greeter) {
      greeter.sayHello("Dave");
   });
}
initialize();

So, a little bit more verbose here, but the advantage is that we have the power to load modules asynchronously at runtime! Although Require provides build tools which let you compile your code into a single (or multiple) file, you are also free to load modules dynamically, on an as-need basis at runtime. Both of these options are very useful when working on large projects where performance is a concern.
I should mention now that one feature of AMD/RequireJS is the ability to load code which was written with CommonJS in mind. Code like this expects an exports variable, which Require can provide if we write our code like this:

app.js

//define an "app" module
define(["greeter", "exports"], function (greeter, exports) {
   exports.initialize = function() {
      greeter.sayHello("Dave");
   }
});

Here all that we do is specify a dependency of “exports,” and then the resulting exports variable can be used just like you would in CommonJS. The reason I mention this alternative syntax is because this is the way that TypeScript actually compiles when compiling to AMD.

Modularization in TypeScript

Essentially, TypeScript just provides syntactic sugar which sits on top of JavaScript but looks and feels a lot like standard OO fare. This extends to modularization as well. TypeScript allows you to define classes (which really just resolve to prototypes) and modules (namespacing), which can be exported and used in other files. TypeScript then compiles these modules into either CommonJS or AMD format. By default it uses CommonJS, but adding the compiler option –module amd allows you to compile AMD-compliant modules. Please note that in order for browser-based AMD TypeScript code to actually run in a browser, you must manually include RequireJS or another AMD implementation on the page.

I will spend most of the remainder of the article focusing on AMD compilation in the browser, since that is the most common and important use case for most developers, and also happens to be the trickiest.
In Visual Studio 2012, you can set up your project to use AMD by editing your project file’s “BeforeBuild” step to include the –module amd parameter, as described here. Note that if you are using AMD (i.e. in the browser) you must have loaded an AMD loader such as RequireJS. Otherwise, your project may compile, but it will fail to work in the browser.

Classes

Before we get into the details of modularization, let’s talk briefly about classes in TypeScript. Before proceeding, it might be a good time to brush up on your JavaScript prototypes-vs-classes, prototypical inheritance-vs-classical inheritance knowledge. If you’ve had a cursory look at TypeScript, you’ve seen that class in TypeScript works out to be a constructor function/prototype in JavaScript.

pony.ts

class Pony {
   bite() {
      alert("Chomp!");
   }
}

compiles to

pony.js

var Pony = (function () {
   function Pony() { }
   Pony.prototype.bite = function () {
      alert("Chomp!");
   };
   return Pony;
})();

Which is basically how TypeScript classes work – syntactic sugar that ultimately resolves to a plain old constructor function in JavaScript. The benefit of this, of course, is that it is considerably easier for a developer steeped in OO to understand this way of doing things than trying to wrap one’s mind around prototypes and constructor functions right off the bat.

Update:
With the 0.9 release of TypeScript, Microsoft added support for a module.exports – style assignment, just as I hoped they would. You can now export and import classes directly, like so:

    // client.ts 
    class Client { 
        constructor(public name: string, public description: string) { } 
    } 
    export = Client; 

    // app.ts 
    import MyClient = require('./client'); 
    var myClient = new MyClient("Joe Smith", "My #1 client");

This is hugely helpful and supercedes about 80% of the information that follows. I may write another blog post on the subject, but probably not since this is now rather self-explanatory. Please consider all export/import information that follows to be deprecated.

Exporting/Importing

To use our Pony class in another TypeScript file, we simply use the export keyword:

pony.ts

export class Pony {
   bite() {
      alert("Chomp!");
   }
}

Which with CommonJS compilation yields this:

pony.js (CommonJS compilation)

var Pony = (function () {
   function Pony() { }
   Pony.prototype.bite = function () {
      alert("Chomp!");
   };
   return Pony;
})();
exports.Pony = Pony;

And with AMD compilation looks like this:

pony.js (AMD compilation)

define(["require", "exports"], function(require, exports) {
   var Pony = (function () {
      function Pony() { }
      Pony.prototype.bite = function () {
         alert("Chomp!");
      };
   return Pony;
})();
exports.Pony = Pony;
});

To user out Pony class, we first must import that file, like so:

app.ts

import Pony = module("pony");
var pony = new Pony.Pony();
pony.bite();

Implicit Modules, or when TypeScript is unwieldy

Wait, that seems a little bit different than we might have expected… Shouldn’t we be able to just say var pony = new Pony()? As it turns out, no. Let’s take a closer look at the compiled output above. Notice that, as mentioned previously, TypeScript uses exports.* to export functions and variables, rather than just returning the object or function desired. Because of this, our Pony constructor function, rather than itself being the exported object, is actually just a method off of the exported module! I like to call this surprising behavior Implicit Modules (my term, good luck googling it) – when exporting a class in a file, the file essentially becomes its own module which contains the class that you wanted to export.

IMHO, what would have been more convenient would have been for TypeScript’s compilation to yield a module.exports-style assignment, which would have enabled us to import the Pony class directly, rather than just as a variable off of some sort of implicit Pony module or namespace.
While this is largely just a bit of a syntactical inconvenience, it can also make it difficult-to-impossible to port over JavaScript code which relies on module.exports, as someone who registered an issue with Microsoft complained. It remains to be seen whether a future modification to the language specification, or some compiler flag of some sort will make it possible to compile this way. As we will see later, when importing JavaScript libraries, this will cause a little bit of difficulty.
One thing that can be done is to use this deficiency as a feature. Rather than authoring a single class per file, it becomes perhaps more desirable to place a set of related classes in a single file. For example:

animals.ts

class Pony extends Animal {
   bite() {
      alert("I, " + this.name + " have bitten you!");
   }
}
class Animal {
   name:string;
   constructor(name:string) {
      this.name = name;
   }
}
var pony = new Pony("Bob");
pony.bite();

app.ts

import Animals = module("animals");
var pony = new Animals.Pony("Bob");
pony.bite();

Inheritance, or when TypeScript is great

In this example, we see both an arguable weakness (implicit modules) and a great strength of TypeScript – classical inheritance! Being able to elegantly define classes which inherit from each other is invaluable in large-scale application development. I consider this one of the greatest strengths of the language. Of course, ultimately it just resolves to JavaScript, but achieving this capability in pure JavaScript is really ugly and nigh-inscrutable. I prefer scrutable. But back to modularization.
When dealing with TypeScript-only modules, the Import/Export system works more or less like a charm. When you want to start including JavaScript libraries, it gets a bit trickier.

Importing JavaScript

In TypeScript, there are two ways to “include” another source file – reference comments and import declarations. Let’s have a look at each.

Reference comments

Reference comments add a dependency on the source file specified. They are only used for compilation purposes, and can be used to provide IntelliSense for JavaScript files. They do NOT affect the compiled JS output. Here is an example:

/// <reference path="pony.ts"/>
var pony : Pony; //compiler now recognizes Pony class.

This tells the compiler that pony.ts will be available at runtime. It does not actually import the code. This can be used if you are not using AMD or CommonJS and just have files included on the page via script tags.

Import declarations

If we want to load a file via AMD or CommonJS, we need to use an import declaration.

import myModule = module("pony");

This tells the compiler to load pony.ts via AMD or CommonJS. It does affect the output of the compiler.

Importing JavaScript

Let’s face it. Most of the libraries we will want to use are not written in TypeScript – they’re all in vanilla JavaScript. To use them in TypeScript, we’re going to have to do a little bit of porting. Ambient Declarations and Declaration Source Files will be our tools.

Ambient Declarations (declare var)

Ambient Declarations are used to define variables which will be available in JavaScript at runtime, but may not have originated as TypeScript files. This is done with the declare keyword.
As a simple example of how this could be used, let’s say your program is running in the browser, and you want to use the document variable. TypeScript doesn’t know that this variable exists, and if we start throwing document’s around, he’ll throw a nice compiler error. So we have to tell him, like this:

declare var document;

Simple enough, right? Since no typing information is associated with document, TypeScript will infer the any type, and won’t make any assumptions about the contents of document. But what if we want to have some typing information associated with a library we are porting in? Read on.

Declaration source files (*.d.ts)

Declaration source files are files with a special extension of *.d.ts. Inside these files, the declare keyword is implicit on all declarations. The purpose of these files is to provide some typing information for JavaScript libraries. For a simple example, let’s say we have an amazing AMD JavaScript utility library, util.js which we just have to have in our TypeScript project.

define([], function() {
   return {
      sayHello: function(name) {
         alert( "Hello, " + name );
      }
   }
});

If we wanted to write a TypeScript declaration file for it, we would write something like this:

export function sayHello(name:string): void;

Declaration source files stand in for the actual .js files in TypeScript-land. They do not compile to .js files, unlike their plain *.ts peers. One way you can think of it is *.d.ts files act as surrogates for their .js implementations, since plain .js files aren’t allowed in TypeScript-land. They simply describe their JavaScript implementations, and act as their representative. What this means is that now you can import JavaScript! Here’s how we would use our util library:

import util = module("util");
util.sayHello("Dave");

This import statement here uses AMD or CommonJS to load the util.js file, the same as if util.js had been the compiled output of a util.ts file. Our util.d.ts provides the compiler/IDE with the IntelliSense to know that a sayHello method exists. The big takeaway here: If you want to include a JavaScript file, you need to write a *.d.ts file.
Note here that we used an Import Declaration to include our .js file. If we had merely wanted to tell the TypeScript compiler that util would be available at runtime (meaning we already loaded it somewhere else, via script tag or RequireJS), we could have used a Reference Comment in conjunction with an Ambient Declaration. To do that, we would first need to change our declaration source file:

interface Util {
   sayHello(name:string): void;
}

This defines a Util interface which we can then use for compilation purposes.

///<reference path="util.d.ts"/>
declare var util: Util;
util.sayHello("Dave");

It turns out that lots of people in the open source community have been cranking out TypeScript interface definitions for some of the most popular JavaScript libraries, including jQuery, Backbone, Underscore, etc. You can find dozens of these on GitHub in the DefinitelyTyped project. The interface definition for jQuery can be found here.

How to be lazy

What if I don’t want to take the time to re-write my .js library in TypeScript, or carefully craft an exhaustive *.d.ts file? It’s not hard to get around. Back to our util.js example. Let’s say that we had another method, sayGoodbye, which we didn’t want to take the time to define in our util.d.ts file, because of our supreme laziness. Simple. Just define a single export function in util.d.ts (one line isn’t going to hurt you!). Then, when you want to use methods that TypeScript doesn’t know exist, just use an Ambient Declaration, like so:

import util = module("util");
declare var unchained:any;
unchained = util;
unchained.sayGoodbye();

The magic here is the Ambient declaration of the unchained variable, which is of type any. The any type tells TypeScript not to worry about typing – this variable could be anything. Trust us.

Dynamically Importing Existing JavaScript Libraries – The Problem(s)

The trickiest part of all this is getting TypeScript to use AMD or CommonJS to import a JavaScript library or module, rather than just making it compile using a reference comment. There are two tricky components to this.

First, if you are using an interface definition like those found online, you can NOT use that file as your *.d.ts in an import declaration. The interface declaration is only used to provide compiler/Intellisense information to the TypeScript compiler – interfaces are different than classes. In order for you to import your external library like we did in our simple util.js example from earlier, you need a different sort of *.d.ts file – one which uses the export keyword.

Second, recall from earlier how TypeScript has what I like to call Implicit Modules when importing files? You can’t directly import a class – you import the file it is in and then get your class definition off the resulting module object. Well, this causes us some grief when it comes to importing JavaScript modules which don’t follow the exports.* pattern in their AMD implementation, since most of the time when you import a “class” (constructor function) in AMD, you expect the imported object to be the constructor function itself.

Static Solution – Exporting to global namespace

The first, and simplest way to use a JS library in TypeScript is to simply make a Reference Comment to the *.d.ts interface definition, make an Ambient Declaration for the variable, and then do the actually loading in your RequireJS configuration, exporting the library into the global namespace. This method is acceptable if you are talking about common core libraries such as jQuery or Backbone, but since it relies on the global namespace it is NOT a recommended solution generally. Here’s what this looks like, using jQuery as an example.
In our index.html, we start our application up by loading Require and pointing it at appConfig.js, a plain JavaScript file which sets up RequireJS and starts our application.

index.html

<script type="text/javascript" src="libs/require.js" data-main="appConfig.js"/>

appConfig.js

require.config({
paths: {
   'jquery': 'libs/jquery-1.8.3.min'
},
shim: {
   'jquery': {
      exports: '$'
   }
}
});
require( ['app', 'jquery'], function(App) {
   App.start();
});

app.ts

///<reference path="jquery.d.ts"/>
declare var $:JQueryStatic; //JQueryStatic is defined in jquery.d.ts
export class App {
   start() {
      $( "#content" ).html( "<h1>Hello World</h1>" );
   }
}

The key here is that jQuery is loaded in a non-AMD, globally scoped fashion. In the shim-jquery-exports-$ section in the RequireJS configuration, you can see that the exports keyword tells Require that when “jquery” is loaded, the result is “exported” into the global variable $. Then in our TypeScript file, we simply add a Reference Comment for our *d.ts interface definition and then make an Ambient Declaration saying that the variable $ will be available at runtime and is of the type JQueryStatic.

This is a great method for application-wide libraries like jQuery, but as I mentioned before, it is NOT advisable to use this willy-nilly due to its reliance on the global namespace as well as its load-everything-up-front approach, which may not be desirable in some larger applications. Also note that anytime you want to include a new JS library, you must change your application-level configuration, and this cannot be done (not easily at least) in TypeScript.

Dynamic Solution

So how do we use TypeScript to dynamically import JavaScript libraries? To get around the first problem mentioned above, what I like to do is to define two separate *.d.ts files: one containing the interface definition you probably pulled off the web, and another which exports a single variable of the type defined in the interface file. Let’s use jQuery as our example again. The jquery.d.ts definition defines a JQueryStatic interface. Lets rename our interface definition file to jquery-int.d.ts, and create a new jquery.d.ts that looks like this:

jquery.d.ts

///<reference path="jquery-int.d.ts"/>
export var $:JQueryStatic;

This will allow TypeScript to compile if we import jQuery like below.

app.ts

import JQuery = module( "libs/jquery" );
var $:JQueryStatic = JQuery.$;
export class App {
   start() {
      $( "#content" ).html( "<h1>Hello World</h1>" );
   }
}

Now we are able to compile in TypeScript. However, let’s say that we have a fairly standard AMD-compliant loader file for jquery, which might look something like this:

jquery.js

define( ["libs/jquery-1.8.3.min"], function() {
   return $;
});

Using an AMD “loader” file like this is a common way of modularizing non-AMD JavaScript libraries. The problem here though is although our jquery.js loader returns $ when imported, in TypeScript our import statement expects an object that has a property of $. This is the second problem I mentioned earlier. My workaround for this is to change my AMD loader file to make it use exports.* just like TypeScript does.

define(["exports", "libs/jquery-1.8.3.min"], function (exports) {
   exports.$ = $;
});

Now when we import our jquery.d.ts in TypeScript, we will have the results we expected: a nice exported module with a $ property that happens to conform to our JQueryStatic definition. After weeks of scouring the web, this is the best method that I have come up with for dynamically importing JavaScript libraries in TypeScript. Let’s review the steps:

Dynamic Strategy Summary

  1. Snag an interface definition (*.d.ts file) off the web, or create one yourself. Remember that you can always be lazy and fall back on the any type.
  2. Rename this interface definition file example-int.d.ts.
  3. Create a new example.d.ts file which exports a single variable of the type defined in your interface definition
  4. Create a “loader”-style file example.js and use exports.* to export the desired library.
  5. Where desired, simply import the example module and find your desired library as a property off of the imported module.

And that’s it! It is a bit involved and definitely more work that I would have liked. I am hoping that the maintainers of the TypeScript language someday soon add the ability to use module.exports like I mentioned earlier, but until then this sort of workaround seems to be the order of the day.

Denouement

To summarize our findings, let’s turn now to an elegantly crafted outline:

  1. TypeScript provides handy-dandy static typing and IntelliSense on top of core JavaScript
  2. Modularization in core JavaScript is crappy to non-existent
  3. AMD and CommonJS are great and allow you to cleanly organize code
  4. TypeScript can do AMD or CommonJS
    1. –module flag let’s you switch between the two
    2. TypeScript inheritance is great (tangential but true)
    3. CommonJS module.exports is not allowed.
    4. TypeScript-to-TypeScript is clean and awesome (with the exception of limitations from c.)
    5. JavaScript-to-TypeScript
      1. Relies on Reference Comments, Import Declarations, Ambient Declarations, and Declaration Source Files
      2. Is fairly simple when using global namespace
      3. Is more involved when loading dynamically
        1. Problems
          1. interface definitions are not the same as exports.
          2. Cannot directly import because of Implicit Modules
        2. Solution: see “Strategy Summary” above

I spent a lot of time trying to figure out how to dynamically import JavaScript libraries, so I hope you find my strategy useful. Other similar sorts of strategies I looked at can be found here and here. The first one is a bit odd and I did not like that it requires (no pun intended) you to use the ugly AMD/Require syntax in TypeScript, and the second forces you to modify the interface definitions you find online or write your own class-based definitions.

I like my strategy because, although there is some overhead in writing AMD loader-files which use exports.*, you can leverage the host of online interface definitions while maintaining TypeScript’s clean and elegant syntax. Please recall though that this technique is not necessary if the library in question is loaded in the global namespace!

If you’ve found an even better way of importing JavaScript, I’d love to hear about it. I would also be totally stoked if you’d follow me on Twitter – @brettjonesdev

This article first appeared on Keyhole Software’s blog. Stay tuned for more of the latest in tech for small shops to the Enterprise!

UPDATE: I have created a simple example of the two main techniques (static versus dynamic imports) I describe here. Check it out on github: typescript-modularizatino-demo

Intro to TypeScript Language and Tooling

TypeScript, Microsoft’s new open source JavaScript derivative, brings static typing along with a number of conventional OOP features to the Wild West of JavaScript. Much like CoffeeScript, this syntactical cousin of Ruby and Python compiles to plain old JavaScript. However, unlike CoffeeScript, TypeScript is in fact a superset of the JavaScript language. What this means is that you can actually write vanilla JavaScript in TypeScript (which is cool).

Language Basics

Static Typing – Hello World

Here’s a simple example of TypeScript’s static typing:

function greet(name:string, times:number, el:HTMLElement) {
    var message: string = "";
    for (var i = 0; i < times; i++) {
        message += "Hello, " + name;
    }
    el.innerHTML = message;
}
greet("Bob", 3, document.getElementById('content'));

If we try to pass our greet function parameters of the incorrect type, TypeScript won’t compile:

greet("Bob", "not a number", document.getElementById('content'));

Object Orientation

In my honest opinion, the greatest strength of TypeScript is its introduction of classic OO constructs like classes and inheritance. Granted, these sorts of things can be done in JavaScript’s prototypical system (see David Pitt’s blog post on the subject), but it tends to be more verbose, a bit confusing and far from elegant. In fact, it is so unwieldy that some popular libraries such as MooTools and Backbone provide their own OO abstractions to shield the common developer from the gritty realities of prototypical inheritance.

TypeScript provides the kind of OO goodies that developers over the past twenty years have come to expect. This can be very useful in helping ease developers coming from a conventional OO background into the wild and wonderful world of JavaScript and prototypical inheritance. Look at the following example of a simple class:

class Animal {
    name: string;
    constructor(name: string) {
        this.name = name;
    }
    sayHello() {
        alert("Hello, my name is " + this.name);
    }
}

This compiles to the following JavaScript:

var Animal = (function () {
    function Animal(name) {
        this.name = name;
    }
    Animal.prototype.sayHello = function () {
        alert("Hello, my name is " + this.name);
    };
    return Animal;
})();

Here we can see that although TypeScript appears to follow a more traditional OOP paradigm, under the covers all it really does is add some syntactic sugar to JavaScript’s basic prototypical inheritance model.

Inheritance

Let’s look at a simple example of one of the most useful of all OO paradigms (and my personal favorite) – Inheritance.

class Animal {
    name: string;
    constructor(name: string) {
        this.name = name;
    }
    sayHello() {
        alert("Hello, my name is " + this.name);
    }
}

class Pony extends Animal {
    sayHello() {
        super.sayHello();
        alert("and I am a pony!");
    }
}

var pony: Pony = new Pony("George");
pony.sayHello();

Pretty cool! I won’t show you what this compiles to here (it’s ugly), but if you’re curious, copy this into Microsoft’s online TypeScript Playground to get a better feel for how TypeScript compilation works.

Plain JavaScript in TypeScript

Although TypeScript allows you to use static typing, at any point in development you are free to fall back to writing vanilla JavaScript. For instance, our original greet method example from earlier could have been written in plain JS:

function greet(name, times, el) {
    var message = "";
    for (var i = 0; i < times; i++) {
        message += "Hello, " + name;
    }
    el.innerHTML = message;
}

Modularization and multi-file

TypeScript provides built-in support for CommonJS and AMD modules. It is quite simple to import and export TypeScript files, just like you would in a server-side language. Importing JavaScript libraries is a bit trickier, but can still be done. I will cover more on this in a later blog post dedicated to the topic, so stay tuned!

Tooling

TypeScript was created by Microsoft, so as you’d expect, the first major IDE to have support for it is Visual Studio 2012. They have a nice plugin that integrates the TypeScript compiler into the IDE. Note that this download includes the TypeScript compiler, which can be run from the command line, as well as the VS plugin (VS 2012 must already be installed when the plugin is installed in order for the IDE to include TypeScript support).

As far as support goes with other IDEs, the current landscape is a bit sparse. WebStorm (my personal favorite web IDE, created by the people who brought you IntelliJ) has support coming in version 6, currently only available in the Early Access Program. There does not seem to be a solid Eclipse plugin yet. There appear to be some offerings available for Sublime Text, emacs and vim.

At the moment, the clear frontrunner – as you might expect – is Visual Studio. Let’s look at what it has to offer.

Visual Studio 2012

You can create a new TypeScript project by selecting “HTML Application with TypeScript.”

This creates a basic project that includes a default.html that loads app.js, the compiled result of app.ts, the main TypeScript file.

Running in Browser

Building our solution uses the TypeScript compiler to generate an app.js output file. To run, we can select what browser we want to use. Like any level-headed developer, I choose Chrome.

Selecting this option opens up a new tab in Chrome running our app:

Debugging

We have two options to debug in Chrome developer tools: debug the compiled JavaScript output, or use source maps to debug our TypeScript files. The first option is simple enough – we just open our developer tools, open up app.js and start setting breakpoints.

Source maps are a bit different. If you’re not familiar with the concept, you can read about it here. Basically, source maps map the compiled, possibly minified code that the browser sees onto the actual source code you wrote, with all its syntactic niceties. This, of course, makes debugging much easier. In TypeScript, adding the -sourcemap switch on compilation generates sourcemap information in the compiled output. Visual Studio adds this option by default, so we don’t have to worry about it here.

To use source maps in Chrome, you must enable the source maps option:

This gives us the option to load app.ts and view our TypeScript code:

These debugging capabilities make real TypeScript development much more practical.

IntelliSense

One of the biggest benefits that comes with using TypeScript is the ability to use powerful IntelliSense. With plain JavaScript’s dynamic typing, it is quite difficult for IDEs to offer safe, clean and reliable IntelliSense capabilities (WebStorm does it the best, in my opinion). With TypeScript, you can rely on such useful operations as Renaming a method or class. This is something very hit-or-miss in pure JS, and will be a great boon when developing large-scale applications.

Takeaway/First Impressions

What to make of TypeScript? The reaction to TypeScript’s release has ranged from dismissive to enthusiastic. Naturally, opponents of static typing dismiss it as an unholy pollution of JavaScript’s type-agnostic purity, whereas fans of compiled languages have great praise for it. Those who are critical of Object Orientation generally will not be impressed, while adherents will be excited to finally have OO available to them in the browser.

My take: it depends on you and your use case.

If you are working on a simple, lightweight web application with no more than a handful of developers, the overhead of compilation and learning new language features will probably not be worth the cost in flexibility and speed of development. You won’t like it.

If, on the other hand, you are working on a large-scale Enterprise application with multiple teams and dozens of developers, TypeScript could very well be the tool that makes a JavaScript-based application feasible. There is a certain degree of safety and stability to be found in static typing, and OO certainly helps prevent repetitive coding tasks. If your developers are all JavaScript gurus with years of experience on the client, you probably don’t need TypeScript. If you have a gaggle of Java/C# guys, TypeScript could be huge for you.

So should you invest in TypeScript? Again, it depends on your team and your project.

I’ll add a final caveat – TypeScript is very new right now. It could be a big risk for an organization to take a leap with TypeScript this early in the game. It certainly helps that a giant like Microsoft is behind it, but it remains to be seen if TypeScript will be a long-lived platform. I would certainly advise caution at this point.

In my next post, I will be examining TypeScript’s modularization techniques and how existing JavaScript libraries can be leveraged, so stay tuned!

UPDATE
Part two on TypeScript modularization is now available here. Enjoy!

Brett Jones, asktheteam@keyholesoftware.com

I would also be honored if you would follow me on Twitter – @brettjonesdev.

This article first appeared on Keyhole Software’s blog. Stay tuned for more of the latest in tech for small shops to the Enterprise!