Monday, December 31, 2012

TypeScript Node.js Development Part 6 - AppFog Deployment

It's been a long and exciting journey, but we now have a pretty good foundation of a Node.js app, tested and debuggable, deployed to Azure. That's great, but I quickly ran into a problem. Apparently the way that Azure Web Site processes are handled means that long-running processes are not allowed, and are automatically killed after about half an hour. What I was trying to write required a timer going off at a certain interval indefinitely, but there was just no way to get this to work in an Azure Web Site. My only option if I was going to stick with Azure was to use a Cloud Service rather than a Web Site, but that would take me out of the free tier, which is quite unacceptable.

After a bit of searching around, I found out about a service called AppFog. AppFog is a "Platform as a Service" or PaaS provider, which basically means that, like Azure, they take out all the hassle of deploying code to "The Cloud". The way it works is simple, you sign up for an account, and create an app by choosing from a template (Node app, etc) and a hosting provider (AWS, etc). Behind the scenes, AppFog will provision the host and deploy the template code and in minutes you'll have a skeleton website ready to go. And best of all there is a generous free tier.

Once set up, all you need to do is download the template source code from the AppFog console, overwrite it with the code that we've been using in Azure, update the environment variables again using the console, then upload the code using a few simple commands:
gem install af
af login
af update [sitename]

There isn't the nice git integration and ability to view and rollback deployments like in Azure, but it does allow long-running processes, and it seems to be a bit easier to use and much more adaptable than Azure.

And I'll leave this series of posts at that, hopefully someone has learned something from all this and decides to give TypeScript Node.js development a go, it's been fun!

Previously: TypeScript Node.js Development Part 5 - Unit Tests and Debugging.

TypeScript Node.js Development Part 5 - Unit Tests and Debugging

When I started thinking about doing some Node.js development, I wasn't sure if I would be able to easily do unit testing and debugging. Pretty much all the Javascript stuff I'd done in the past were not tested at all and used console.log as the only form of debugging. That was fine for the front-end scripts I was writing, but for "serious business" backend code, testing and debugging were pretty important to me. I was pleased to find out that this is something that is very possible in Node, and although I don't think there's a way to debug through TypeScript code yet, debugging through the compiled Javascript can be done, and that should be enough for me.

Let's start with debugging, which is actually quite simple to do using Node Inspector and Chrome (or any other WebKit browser). First we need to install Node Inspector, I install this globally since it's something that I want for all my node projects:
npm install -g node-inspector

We now start up our app in debug mode:
node --debug app

And, in a separate console window, start up Node Inspector:
node-inspector

If that all works, you'll be able to open Chrome, go to your app (e.g. http://localhost:1337/) and in another tab, go to the inspector page (e.g. http://localhost:8080/debug?port=5858). What you see on the inspector page should be pretty familiar if you've ever used Chrome's Javascript debugging tools.


If you play around with this a bit, you'll see that you can do anything you would normally do when debugging programs - add breakpoints, watch variables, check the call stack, run code in the console, etc. You can even step into all the node packages you're using, which can be very useful. The one thing that is missing is debugging through TypeScript code rather than the compiled Javascript code.

The intended solution for this is to generate source maps for the TypeScript code, and you can do this as part of the usual Visual Studio build by editing the "BeforeBuild" target command to be:
<Target Name="BeforeBuild">
    <Exec Command="&quot;$(PROGRAMFILES)\Microsoft SDKs\TypeScript\0.8.0.0\tsc&quot; -sourcemap @(TypeScriptCompile ->'&quot;%(fullpath)&quot;', ' ')" />
</Target>

I'm sure that can be done through Visual Studio somehow but I just hand-edit the .csproj file. After this is enabled, building the project will generate .js.map files as well as the .js files for each .ts file. These .map files allow debuggers to interpret the Javascript code as TypeScript, but unfortunately this is not supported in node-inspector yet. The bright side is that it does work on client-side code, as long as you enabled source maps in Chrome:


For unit testing, there are a number of options including Vows, Expresso, Nodeunit, and even just the built-in  assert functions, but in the end I decided to go with Mocha. I must admit that the main reason for my choice was because there were already TypeScript bindings for it in github, but after using it for a while I'm pretty happy with the way it works, especially because it is very easy to test synchronous as well as asynchronous code.

To get started, let's create a simple class (Dog.ts) with only a constructor that takes a parameter, and an accessor for that member:
export class Dog {
    constructor (private name: string) { }
    getName() { return this.name; }
}

Now, after adding mocha.d.ts to our definitions list, we can write a simple test for this class (tests/dogTest.ts):
///<reference path='../app.d.ts' />

import assert = module("assert")
import dog = module("../Dog")

describe('Dog', function () {
    describe('#getName()', function () {
        it("should return the name it's constructed with", function () {
            var fido = new dog.Dog("Fido");
            assert.equal(fido.getName(), "Fido");
        });
    });
});

To run this test, all we need to do is install mocha globally, then run the mocha command in our program directory, and it will take care of finding and running the tests for us:
>npm install -g mocha
>mocha
.
 
 √ 1 test complete (1 ms)

But what if you have some asynchronous code, such as a function with a callback, and you want to ensure that the callback is called before the test ends? Mocha handles that with an optional callback of its own called done, if this callback is present in an "it", the test will not succeed until it is called. As an example,  we can add this function to our dog class:
fetch(gotTheBall: () => any) { setInterval(() => gotTheBall(), 100); }

And a test for this function:
    describe('#fetch()', function () {
        it("should get the ball, good dog!", function (done) {
            var fido = new dog.Dog("Fido");
            fido.fetch(() => {
                done();
            });
        });
    });

If the done function was not present here, the test would end without waiting for the dog to fetch the ball, which would be very unsatisfying.

So that's how you write a simple synchronous and asynchronous tests, but in more complex tests, sometimes you need to mock out a certain dependency and assert that a function is called on it, and sometimes you need to check that a HTTP request is made but you don't actually want to make that request. Node has solutions for this too, and there are several options, but what I decided to use was Gently for general mocking/stubbing, and Nock for mocking HTTP requests (which I usually make by using the request package). Currently, only definitions for request are in the typescript-node-definitions repo, but I've made a fork which contains definitions for Gently and Nock, although by the time you read this that might already have been pulled in. Add these packages to your package.json file, and the definitions to your add.d.ts file, and we're ready to go.

Both of these packages have good documentation and readable code, so to avoid this post getting too much longer, I'll just give you some sample code. Firstly, to test Gently, we'll give our dog an external voice box.
export class Dog {
    constructor (private name: string, private woofer?: Woofer) { }
    ....
    bark() { this.woofer && this.woofer.woof("woof"); }
}
export class Woofer { 
    public woof(sound: string) { console.log(sound); }
}

Then we'll write a test which will mock out the woofer:
import gently = module("gently")
...
    describe('#bark()', function () {
        it("should invoke the woofer", function () {
            var woofer = new dog.Woofer();
            var fido = new dog.Dog("Fido", woofer);
            var mock = new gently();
            mock.expect(woofer, "woof", 1, (sound) => {
                assert.equal(sound, "woof");
            });
            fido.bark();
            mock.verify();
        });
    });

What's happening here is that we're using Gently to say that we expect woofer.woof to be called once, with "woof" as the parameter. If you run this test, you'll notice that it passes, but the console.log never happens, which is what we would expect to happen since it has been mocked out by Gently. Note that the call to verify is optional, since that happens automatically when the gently object goes out of scope, but it is left in here for clarity.

Now to test Nock, we'll get our dog to search for the body of a missing person (using Google of course), but we'll use Nock to make sure that no requests are actually made and so that we can be sure we know what the web request will return.
///<reference path="./app.d.ts">
import request = module("request")
export class Dog {
    ...
    search(done: (string) => void) { 
        request("http://www.google.com/?q=missing%20person", (err, response, body) => { 
            (!err && response.statusCode == 200) ? done(body) : done(null);
        });
    }
}
...
...
import nock = module("nock")
...
describe('Dog', function () {
    ...
    describe('#search()', function () {
        it("should return body if found", function (done) {
            var fido = new dog.Dog("Fido");
            nock("http://www.google.com")
                .get("/?q=missing%20person")
                .reply(200, "found it");
            fido.search((result) => { 
                assert.equal("found it", result); 
                done(); 
            });
        });
        it("should return null if not found", function (done) {     
            var fido = new dog.Dog("Fido");
            nock("http://www.google.com")
                .get("/?q=missing%20person")
                .reply(404);
            fido.search((result) => { 
                assert.equal(null, result); 
                done(); 
            });
        });
    });
});

Gently and Nock have many more features of course, but this should give you an idea of how handy they can be when writing tests.

One more thing I want to go over is to tie together the theme of this post and show you how to debug these tests. Using all that we've covered in this post, debugging is easy. All you need to do is run mocha and get it to automatically put a breakpoint on the first line, then use node inspector.
> mocha --debug-brk
debugger listening on port 5858
> node-inspector
visit http://0.0.0.0:8080/debug?port=5858 to start debugging

Open up your browser and go to the normal node-inspector address (http://localhost:8080/debug?port=5858). In an ideal world you would be able to see your test code in the list of scripts, but unfortunately this was not the case for me and I had to do a few hacks to get it to work (hopefully this will be fixed soon). My problem is that the debugger starts debugging the mocha source code but doesn't let me see my test code and add breakpoints there, so I had to manually add a breakpoint by adding "debugger;" to the top of my test file. After I did this, I was able to continue the debugger after the mocha code, and then see my code when the second breakpoint was added. From this point you can add breakpoints to and debug your code as usual through the node inspector page.

Wow that was a long post, the next and final part will cover using AppFog rather than Azure and it will be a lot shorter. Here is the final Visual Studio template I'll provide, which should have all the code up to the end of this post.

Previously: TypeScript Node.js Development Part 4 - More Packages, next: TypeScript Node.js Development Part 6 - AppFog Deployment.

Sunday, December 30, 2012

TypeScript Node.js Development Part 4 - More Packages

In this post I'll go through how to add some useful tools to your Node.js TypeScript app - Underscore for handy utility functions, MongoDB for persistence, and Socket.IO for real-time client-server communication.

Since this is Node, nice people have already made packages for these (underscore, mongodb, socket.io) and adding them is simply done by updating the package.json file:
{
  "name": "package-name"
  , "version": "0.0.1"
  , "private": true
  , "dependencies": {
      "express": "2.5.8"
    , "ejs": ">= 0.8.3"
    , "jade": ">= 0.27.7"
    , "underscore": ">= 1.4.2"
    , "mongodb": ">= 1.1.11"
    , "socket.io": ">= 0.9.11"
  }
}

And since these packages are already included in soywiz's definitions, getting them working in TypeScript is as easy as adding the definitions to the app.d.ts file:
/// <reference path="./node-definitions/node.d.ts" />
/// <reference path="./node-definitions/express.d.ts" />
/// <reference path="./node-definitions/mocha.d.ts" />
/// <reference path="./node-definitions/underscore.d.ts" />
/// <reference path="./node-definitions/mongodb.d.ts" />
/// <reference path="./node-definitions/socket.io.d.ts" />

To test that underscore works, we can add some code to one of our test routes:
import _ = module("underscore")
app.get('/testUrl', function(req, res) {
    console.log('test url ' + req.query['testQS']);

    // Test underscore
    var underscoreTest: string = "";
    var array:string[] = ["a", "b", "c"];
    _.each(array, (item) => { underscoreTest += item });

    res.send(underscoreTest + " env = " + app.settings.env, 200);
});

If you type "_" in to Visual Studio, you'll notice that the TypeScript definitions have given us Intellisense for Underscore, nice!


Socket.IO is also easy to test out, using some of their sample code. We can add this code to our app (again with full Intellisense):
import io = module("socket.io");
var sio = io.listen(app);
sio.sockets.on('connection', function (socket) {
    socket.emit('news', { hello: 'world' });
    socket.on('my other event', function (data) {
        console.log(data);
    });
});

And this code to our index.jade file:
script(src='/socket.io/socket.io.js')
script(type='text/javascript')
  var socket = io.connect();
  socket.on('news', function (data) {
    console.log(data);
    socket.emit('my other event', { my: 'data' });
  });

npm install, then run the app, and we see some console output on the server side logs and the browser, indicating that everything is all going peachy.

MongoDB is a bit more complicated. First, we need to get a local server running so that we can do some testing locally and luckily there is a good tutorial for that over on the MongoDB site. After installation, run mongod.exe and we are ready to write some code to utilize the server.

Here's something I prepared earlier (based on the node package docs), some code that allows addition and querying of a key-value pair to the database (model.ts):
///<reference path='app.d.ts' />

import mongodb = module('mongodb');

interface TestDoc {
    key: string;
    value: string;
}

export class Model {
 private server: mongodb.Server;
 private client: mongodb.Db;

 constructor () {
        var dbname: string = 'testdbsdf';
        var host: string = 'localhost';
        var port: number = 27017;

     this.server = new mongodb.Server(host, port, { auto_reconnect: true });

     this.client = new mongodb.Db(dbname, this.server, { safe: true });
        this.client.open((error) => {
            if(error) { console.error(error); return; }
        });
 }

 putTestDoc(doc: TestDoc, callback: (doc: TestDoc) => void, errorcb: (error: any) => void): void {
     this.client.collection('TestDoc', function (error, docs) {
         if (error) { console.error(error); errorcb(error); return }

         docs.insert(doc, function (error, object) {
             if (error) { console.error(error); errorcb(error); return; }
             callback(object)
         });
     });
 }

 getTestDoc(key: string, callback: (doc: TestDoc) => void, errorcb: (error: any) => void): void {
     this.client.collection('TestDoc', function (error, docs) {
         if (error) { console.error(error); errorcb(error); return; }
            
            docs.findOne({'key': key}, function(error, doc) {
               if(error) { console.error(error); errorcb(error); return; }
               callback(doc);
            });
     });
 }

 getAllTestDocs(callback: (docs: TestDoc[]) => void, errorcb: (error: any) => void): void {
     this.client.collection('TestDoc', function (error, docs) {
         if (error) { console.error(error); errorcb(error); return; }
            
         docs.find({}, { limit: 100 }).toArray(function (err, docs) {
             if (error) { console.error(error); errorcb(error); return; }
             callback(docs);
         });
     });
 }
} 

We can now add some routes that use this class:
import model = module("./model")
app.get('/testMongo/:key/:value', function(req, res) {
    // Add the key/value pair to the DB and then fetch and return it
    database.putTestDoc({ key: req.params.key, value: req.params.value }, function () {
        database.getTestDoc(req.params.key, function (doc) {
            res.send("key = [" + doc.key + "] value = [" + doc.value + "]", 200);
        }, function (err) { res.send(err, 200); });
    }, function (err) { res.send(err, 200); });
});

app.get('/testMongo', function(req, res) {
    // return a list of all pairs
    var response: string = "";
    database.getAllTestDocs(function (docs) {
        _.each(docs, (doc) => { response += ("key = [" + doc.key + "] value = [" + doc.value + "]"); });
        res.send(response, 200);
    }, function (err) { res.send(err, 200); });
});

This is very simplistic - for example, it doesn't check for duplicate keys, but it's good enough to confirm that the database is set up correctly.

So that's all set up locally, but what about ~The Cloud~? Thankfully, The Cloud is generous, and there is a free service to set up cloud-based MongoDB servers called MongoLab. Sign up for an account, create a database, and we are nearly ready to go. Thanks, The Cloud! Before we can use this, we need to modify our model.ts file a bit, so that it can access MongoLab's database. We also now need to authenticate with our username and password. Since we all know that we should never put sensitive information like this in code, we will do this using Azure's app settings. First, we need to update our Model's constructor:
 constructor () {
        var dbname: string = process.env['MONGO_NODE_DRIVER_DBNAME'] || 'testdb';
        var host: string = process.env['MONGO_NODE_DRIVER_HOST'] || 'localhost';
        var port: number = parseInt(process.env['MONGO_NODE_DRIVER_PORT']) || 27017;

     this.server = new mongodb.Server(host, port, { auto_reconnect: true });

     this.client = new mongodb.Db(dbname, this.server, { safe: true });
        this.client.open((error) => {
            if(error) { console.error(error); return; }

            var username: string = process.env['MONGO_NODE_DRIVER_USER'];
            var password: string = process.env['MONGO_NODE_DRIVER_PASSWORD'];
            
            if (username && password) {
                this.client.authenticate(username, password, function (error) {
                    if (error) { console.error(error); return; }
                });
            }
        });
 }

Then we need to put those new settings into our Azure app settings section (in the dashboard, under Configure.

Save those, upload the new code to Azure, and we're up and running all over The Cloud. That's it for now, in the next post, I'll go over testing and debugging your app. As always, here is a Visual Studio template up to this point.

Previously: TypeScript Node.js Development Part 3 - Twitter Bootstrap, next: TypeScript Node.js Development Part 5 - Unit Tests and Debugging

TypeScript Node.js Development Part 3 - Twitter Bootstrap

This is going to be a quick post since I only want to cover how to get a jade layout working with Twitter Bootstrap. Bootstrap is a front-end framework that includes a nice standard UI, an easy way to make a neat layout that updates depending on the size of the window, and a bunch of neat Javascript features like popups, dropdowns, and alerts. It's a great way to start off a site, especially for people like me who are horrible at graphic design.

To get this started, first I'm going to get rid of the original CSS code, but leave the file there in case I want to add anything else later. Getting the site "bootstrap enabled" is a simple matter of referencing the bootstrap CSS and JS files, and I'm also going to include jQuery since the Bootstrap Javascript code requires it, and also because it's something that is pretty useful on its own. With these changes, the layout.jade file now looks like:
!!!
html
  head
    title Page Title
    link(rel='stylesheet', href='//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/css/bootstrap-combined.min.css')
    link(rel='stylesheet', href='/css/style.css')

  body
    #header
      script(src='http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js')
      script(src='http://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/js/bootstrap.min.js')

    #container!= body

The basic way to layout a Bootstrap page is to use row divs to separate vertical parts of the page and column spans with optional offsets to separate horizontal parts of rows. The Bootstrap docs explain this in more detail, but for my simple index page, I'm going to enclose all my content in one row which is 4 columns wide and offsetted 2 columns from the left, and in jade that looks like this:
.row
  .offset2.span4
    [content goes here]

My content is going to be the title and test array from part 2, then some code which tests that jQuery and Bootstrap are both hooked up correctly and working. The jQuery test is a simple accessor that modifies some HTML. The Bootstrap test is a bit more involved - it's a button that when clicked will open up a modal dialog. Translating some jQuery code and sample Bootstrap code to Jade, we get this:
    h1= title
    p Welcome to #{title}

    ul
    - each test in testArray
      li
        a(href= "/user/"+test)
          b= test

    #jquery-test

    script(type='text/javascript')
      $("div#jquery-test").html("jQuery works!")

    a#bootstrap-test.btn(href="#",role="button") 
      i.icon-thumbs-up
      | Bootstrap Modal

    #myModal.modal.hide.fade(role="dialog")
      .modal-header
        button.close(type="button", data-dismiss="modal") x
        h3 Modal Test

    script(type='text/javascript')
      $('#bootstrap-test').click(function() { $('#myModal').modal() });

Load that up, and we see the reassuring "jQuery works!" and a button which, as expected, opens up a modal dialog.

The final step I wanted to include was to add some Google Analytics tracking code, since that is something that I want in all of my sites. This gets added to the layout file, and in Jade it looks like:
    script(type='text/javascript')
      var _gaq = _gaq || [];
      _gaq.push(['_setAccount', 'ANALYTICS-ID']);
      _gaq.push(['_trackPageview']);
      (function () {
        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
      })();

And that's all I wanted to cover in this post. As with part 2, I've made a Visual Studio template which includes these changes.

Previously: TypeScript Node.js Development Part 2 - Standard Packages and Azure Deployment, next: TypeScript Node.js Development Part 4 - More Packages.

Saturday, December 22, 2012

TypeScript Node.js Development Part 2 - Standard Packages and Azure Deployment

In Part 1 I went through the process of making a basic Node.js app using TypeScript in Visual Studio. In this post, I'll make the app a bit less basic, and deploy it to Azure (a.k.a. "THE CLOUD").

To make this server a bit easier to work with, I'll use three Node.js packages - express for routing etc, ejs for templating, and jade for confusing-looking HTML that seems like it's an interesting thing to try out. Since we're using Node.js, adding these packages is easy, just create a package.json file alongside your app.ts file:
{
    "name": "package-name"
  , "version": "0.0.1"
  , "private": true
  , "dependencies": {
      "express": "2.5.8"
    , "ejs": ">= 0.5.0"
    , "jade": ">= 0.0.1"
  }
}

Then run "npm install" in the app folder.

This pulls in the packages, but TypeScript doesn't know how the express code is defined until we use the definition provided by node-definitions (which we covered in part 1). You could just add "/// <reference path="./node-definitions/express.d.ts" />" to the top of your app.ts file, along with the node.d.ts reference, but a nicer way of doing this is to separate all the definition references to another file, app.d.ts:
/// <reference path="./node-definitions/node.d.ts" />
/// <reference path="./node-definitions/express.d.ts" />
And reference "app.d.ts" at the top of all your TypeScript files. This way, you can add references to your app.d.ts file as required, and the definitions will be available in all your source code files.

I won't go into details about express, ejs, or jade, firstly because I don't really understand it in-depth yet, and secondly because I think the code is pretty self-explanatory. The new app.ts, with some sample get and post URLs, looks like this:
///<reference path='app.d.ts' />

import http = module("http")
import url = module("url")
import routes = module("./routes/index")
import express = module("express")

var app = express.createServer();
var port = process.env.PORT || 1337;

// Configuration
app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.static(__dirname + '/public'));
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
  app.use(express.errorHandler());
});


// Routes

app.get('/', routes.index);

app.get('/testUrl', function(req, res) {
    console.log('test url ' + req.query['testQS']);
    res.send('ok', 200);
});

app.get('/testUrl/:folder', function(req, res) {
    console.log('testing folder ' + req.params.folder);
    res.send('ok', 200);
});

app.post('/testPost/:userid/newboard', function(req, res) {
    console.log('testing post ' + req.params.userid + ', ' + req.param('postdata'));
});

app.listen(port, function(){
    console.log("Express server listening on port %d in %s mode", port, app.settings.env);
});

export var App = app;

We also have a separated route file in routes/index.ts - using routes specified inline or in external files is a matter of preference but I've included both just so you can see how it works:
///<reference path='app.d.ts' />
import express = module("express")
export function index(req: express.ExpressServerRequest, res: express.ExpressServerResponse){
    res.render('index', { title: 'Page Title', testArray: ["1", "2", "3", "4"] })
};

And our jade "HTML" looks like this:

views/index.jade
h1= title
p Welcome to #{title}

ul
- each test in testArray
  li
    a(href= "/user/"+test)
      b= test

views/layout.jade
!!!
html
  head
    title PageTitle
    link(rel='stylesheet', href='/css/style.css')
  body
    #header
      script(src='http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.min.js')
    #container!= body

Finally we have some basic css (public/css/style.css) that I must have gotten from some example code somewhere:
html { background-color: #f9f9f9; margin: 0; padding: 0; }
body { margin: 0 auto; padding: 0; font-family:"Segoe UI","HelveticaNeue-Light", sans-serif; font-weight:200;}
h1, h2, p, summary, footer, li { line-height: 170%; }
h1, h2 { border-bottom: 1px solid #aaa; font-family:"Segoe UI Light","HelveticaNeue-UltraLight", sans-serif; font-weight:100; }
h2 { font-size: 16pt; }
p { margin: 1em 20px 0 20px; }
ul { margin-top: 1em; }
#footer { font-style: italic; color: #999; text-align: center; padding: 1em 0 2em 0; margin-top: 1em; font-size: 80%; }
em { letter-spacing: 1px; }
li { margin-left: 1em; }

After all of this code, you should now be able to build the project and run "node app", then test out the various URLs and check out how the jade template is translated to HTML.

Now we can move onto something pretty awesome, deploying this code to Azure - which has a free tier that allows you to run up to 10 web sites for free. The Azure team has a really good tutorial that goes through setting up a new Azure Node.js website and getting it ready for git deployment, and they describe the process a lot better that I can, so go ahead and read through that, but instead of using their sample Node.js code, use the code that we have just written.

If you're back, hopefully you've managed to deploy this code to Azure, if so well done! The only thing I want to add is that if you're like me you don't like the idea of publishing a whole lot of files that are not needed for the web server. To avoid this, you can make a .gitignore file that includes things like the node definitions and useless dll files, as well as local copies of the node modules (since Azure will automatically npm install your app once deployed):
bin/
obj/
node_modules/
node-definitions/
[appname].csproj
[appname].csproj.user
[appname].sln
[appname].v11.suo

So there you have it, Node.js code, written in TypeScript, built using Visual Basic, running on Azure. This post was mainly just code or links and not much instructions, but hopefully it is useful for someone. Since this is starting to involve a bit of code, I've made a Visual Studio template so you can quickly make a new project with everything set up for you. However, things like node-definitions and possibly other packages will be a bit out of date and may need to be updated.

The next part will cover getting a basic front-end framework up and running.

Previously: TypeScript Node.js Development Part 1 - Getting Started, next: TypeScript Node.js Development Part 3 - Twitter Bootstrap

TypeScript Node.js Development Part 1 - Getting Started

Note: This information is now a bit outdated, see this blog post for a rundown of the most recent Node.js tools in Visual Studio. Also check out my blog post about getting started with Node.js using TypeScript in WebStorm

I've recently started doing some development in a new environment - coding Node.js apps in TypeScript using Visual Studio, and deploying to "The Cloud". Despite a few small roadblocks, and my personal hate for the term "The Cloud", I've found it to be quite a rapid development path, and for small projects at least I think it's my favourite environment to work with so far. When I first started out, I couldn't find many good introductory tutorials about how to get this environment going, so in this small series of posts I'll try to go through what I did to get started.

The end result here will be a basic Node.js app along with all the "good stuff" of modern software development including type checking, unit tests, debugging, and easy deployment. I'll also include some handy additions like connecting to a MongoDB server and using Twitter Bootstrap as a front-end framework. And best of all, everything I use is free! Perfect for the people like me who are doing this for entertainment rather than income.

As a first step, I'll go for the most basic Node.js Hello World app, built using Visual Studio, running as a local server. I'm going to assume you know what TypeScript is, if not you can read about it here. The first thing you'll need to do is quite obvious, download and install Visual Studio Express 2012 for Web. After that you're going to need to download the TypeScript addon, which will allow you to compile TypeScript files and make new ones that are automatically "attached" to the compiled JavaScript file. You need to close Visual Studio to install this, but I think I also had to restart my comptuer, so if the next step doesn't work for you, try turning it off and on again. Now you should be able to create a new project from the "HTML Application with TypeScript" template under C#. This gets you a basic project with some client-side TypeScript code, which can be compiled into JavaScript using Build Project. For some reason it also creates a dll file, which is something that you'll just have to ignore.

But we are not doing this for client-side TypeScript, we want a Node.js app! So go ahead and delete the code in the project, and add a new "TypeScript File" item called "app.ts". We can try to make this file the TypeScript version of the usual basic Node.js app:
import http = module('http')
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');

But if you try to compile that, you'll get a whole lot of errors and an invalid JS file. This is happening because the TypeScript file doesn't know about the Node.js codebase yet, and can't find the http module. Thankfully, a lovely gentleman has made a github project which provides TypeScript definition files for many common Node.js packages (including definitions for Node itself). So go ahead and clone or download that, and put it in the same folder as your app.ts file. You can then add:
/// <reference path="./node-definitions/node.d.ts" />
to the top of your app.ts file. Take a moment now to bask in the glory that is auto-complete for Node.js. Type in "http." or "console." and witness the beauty:


Translating this from TypeScript into English, it means: createServer is a function, the first (and only) parameter, requestListener, is optional, and is a callback which takes 2 parameters - request is of the type ServerRequest in the http module, and response is of the type ServerResponse in the http module. The callback does not return anything, but the createServer function returns an object of the type Server in the http module. And you found out all this without even having to look at any API docs! After you get over your gobsmacked amazement, build the project and run the app using:
node app.js

Then browse to http://127.0.0.1:1337/ and you should see the two words every programmer loves seeing:

I'll leave it at that for now, but soon I'll make another post which will go through the process of using some packages to make this more of a normal web server, and publishing the app to Azure.

Next: TypeScript Node.js Development Part 2 - Standard Packages and Azure Deployment.

Saturday, December 1, 2012

Zombie AI

Today my issue of Coder Weekly arrived, and one article got my attention straight away - Programming AI Bots for Zombie Dice. Zombies, dice, AI, and Python, what's not to like?

The article is about a fairly simple dice game, and an AI framework that has been built around it. The challenge is to come up with a bot written in Python that can beat random rolls and some other pre-built bots. I needed a bit of Python practice, so being the person that I am, I thought this would be a great way to spend a Saturday afternoon.

The game involves rolling a collection of 13 dice, of 3 different colours, which have different amounts of 3 different icons on their faces. I hate probabilities, so when I saw these relatively small numbers I immediately started thinking of a brute force way to solve the problem. You could easily calculate the different possible combinations of colours of dice that would come out of a roll, and using those combinations, you could calculate the probability of all permutations of the faces for those colours. Once that was all calculated, you could use those probabilities to work out the chance that the next roll will be a good one or not.

So that's what I did! Unfortunately the results were ... underwhelming, even after trying several different settings for the acceptable amount of risk vs the reward. One improvement I thought of was that if the bot was winning the game then it should play more conservatively, and if it was losing then it might as well play a little riskier. The results were still not spectacular, but after a lot more tweaking of configuration I managed to get results almost as good as the other bots.

I'm sure there is a sweet spot with the configuration that I could find in some scientific way, but that is the boring part of science so I'm happy to call it a day. That is my story for today, and here is the code.