Saturday, December 22, 2012

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.

8 comments:

  1. Hi - don't know if it's a recent change to Typescript, but the reference line you posted didn't work for me until I added the closing slash to the <reference /> tag. Hope that helps someone else who's wondering why it's quietly ignoring their definitions!

    ReplyDelete
    Replies
    1. Thanks, updated! Must have been a formatting glitch.

      Delete
  2. how do get node running?

    ReplyDelete
    Replies
    1. Check out the node site - http://nodejs.org/. There should also be plenty of introductory tutorials online.

      Delete
  3. The line 1 in the image one was not compiling. I had to change it as below shown to get it working.
    // //import http = module('http')
    var http = require('http');

    ReplyDelete
  4. class Greeter {

    constructor(public greeting: string) {}

    greet() {
    var http = require('http');
    var tmp = this.greeting;
    return http.createServer((request, response) => {
    response.statusCode = 200;
    response.setHeader('Content-type', 'text/plain');
    response.write(tmp);
    response.end();
    });
    }

    };
    var greeter = new Greeter("Hello, world!");

    greeter.greet().listen(1337, '127.0.0.1');
    console.log('Server start.');

    ReplyDelete
  5. but there's no code hintion
    if you go:
    var http = require('http');;
    http.......
    VS gives you nothing

    ReplyDelete
    Replies
    1. Not sure what's happening, it's been a while since I've used Typescript in VS so they might have changed something.

      Delete

Note: Only a member of this blog may post a comment.