0 comments

So I’m working on setting up a small presentation for work and really like the simplicity of reveal.js. I’ve toyed around with some of the node-js plugins before and really like the “Server side speaker notes” plugin, which lets me view my speaker notes on a different device than the one running the presentation. I’ve used my Surface 2 for this purpose before with great success.

Anyway, for this presentation I decided it would be fun to host it on the web so I could just give people the URL later on, instead of distributing the slides via PDF or PowerPoint or the like.

So, why not host the presentation in an Azure Website?

Prerequisites:

 

First of all I clone the reveal.js repo from Github.

image

Then, to be able to run the speaker notes server extension on Azure, I need to modify it slightly. So, in the plugin\notes-server directory, open index.js in your favourite editor.
Around line 13 you should find the server port definition (set to 1947). Change this to process.env.PORT:

image

That’s all you need to change in this file. Remember to commit your changes to the local git repo.

image

There’s one more change you need to make, and that is to enable the speaker notes extension in your presentation. Follow the short guide here for instructions. It’s basically a question of adding two lines inside the dependencies section at the bottom of the presentation html page.

Now, to run on Azure you need to tell IIS to run the iisnode extension for your site. To do this, drop a web.config file in the root of the site, with the following settings:

<configuration>
	<system.webServer>
		<handlers>
			<!-- indicates that the app.js file is a node.js application to be handled by the iisnode module -->
			<add name="iisnode" path="plugin/notes-server/index.js" verb="*" modules="iisnode"/>
		</handlers>
		<rewrite>
			<rules>
				<!-- Don't interfere with requests for logs -->
				<rule name="LogFile" patternSyntax="ECMAScript" stopProcessing="true">
					<match url="^[a-zA-Z0-9_\-]+\.js\.logs\/\d+\.txt$"/>
				</rule>
				<!-- Don't interfere with requests for node-inspector debugging -->
				<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
					<match url="server.js\/debug[\/]?"/>
				</rule>
				<!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
				<rule name="StaticContent">
					<action type="Rewrite" url="public{REQUEST_URI}"/>
				</rule>
				<!-- All other URLs are mapped to the Node.js application entry point -->
				<rule name="DynamicContent">
					<conditions>
						<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
					</conditions>
					<action type="Rewrite" url="plugin/notes-server/index.js"/>
				</rule>
			</rules>
		</rewrite>
	</system.webServer>
	<system.web>
		<compilation debug="true"/>
	</system.web>
</configuration>

Notice that the iisnode handler gets configured to point to the notes-server plugin and that all dynamic URLs are also mapped there. This ensures that the main entry point to our application is through that handler.

Save the file as web.config and add & commit it to the git repo.

image

Now we’re basically ready to push our presentation to Azure. After running the cmdlet Add-AzureAccount, you’re ready to create an Azure Website:

New-AzureWebsite testpresentation -Git

After a few seconds, Azure will have set up your website for you as well as add a remote to your local git repo, named “azure” (That’s what the –Git part does).

You also want to enable websockets on your new website. Run the following command:

Set-AzureWebSite -WebSocketsEnabled 1

All that’s left to do now is to push your presentation up to your newly created website:

git push azure master

The deployment will now run and set up your site for you in Azure, including installing all the required node.js modules. 10-15 seconds later, you should see a "Deployment Successful" message.

If you go to the URL you created above, in this case http://testpresentation.azurewebsites.net*, your presentation should appear, including a popup with your speaker notes. The URL in the popup window can be opened on any other device to give you speaker notes "disconnected" from your main presentation. This is extremely handy when presenting in a place where you don't necessarily have a dual-monitor setup. Instead, you can simply view your notes on your phone or tablet.

Awesome, right?

* Disclaimer: I won’t promise to keep this site online forever

0 comments

I recently discovered that my old GPG key had expired (truthfully I hardly ever used it). And of course I had forgotten to  generate a revocation certificate back then. So I generated a new key. This blog post is mainly just to verify that the key I published below does, in fact, belong to me.

If you want to add me to your “web of trust” by signing the key for me, I would be really happy. Let me know if you do!

Here’s the entire key, which has fingerprint 78189E24005B09330CF62536416C5A0DD9FA2EE5.You might want to check the MIT Key Server for a version with more trust signatures :)

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2.0.22 (MingW32)

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
iAbv4LyaISXKObAMJYvra3tuqw==
=W/UQ
-----END PGP PUBLIC KEY BLOCK-----

Edit: I just managed to revoke my old cert, so the one above is now the only one active for my email address.

0 comments

Today, the last day of GOTO, I spoke to a number of different people whom I knew might have an opinion on Anders Hejlsberg's new language, TypeScript. Yesterday's post was mainly a "brain dump" of my notes from the talk. Now after having had time to digest what I saw, I thought I'd make a couple of observations.  

Firstly, TypeScript IS JavaScript. It is not a new syntax like CoffeeScript, and it's not an entirely new language that incidentally can be compiled to JavaScript but really wants to replace it completely, like Google's Dart project.

TypeScript, in my mind has two sides to it. Firstly, as Anders spent a lot of time pointing out, it extends JavaScript with static typing. Secondly, it introduces a class-based OO model that will be much more friendly to C# and Java developers than the traditional prototype-based model that JavaScript uses. The static typing system is, as I pointed out in my post from yesterday, applied using a postfix syntax, where types are appended after the name of the variable. Static typing allows the compiler to perform checks of our code to ensure that when I pass parameters in my method calls, they are indeed of the right type. But more importantly, it enables our tools to help us during development. Here's an example of types in action:

function add(a: number, b: number) {
   return a + b;
}

In the above example, the compiler will throw an error if I try to pass in the parameters as strings or any other type than numbers. An added bonus is that the return type can be inferred, since the compiler knows the types that are being dealt with in the method body.

One of the cool things about TypeScript's interface system is that objects don't have to explicitly inherit from the interface. All they need to do is to match the definition to work. For example: 

interface Person {
  firstName: string;
  lastname: string;
}

function Greet(Person person) {
   return "Hello " + person.firstName + " " + person.lastName;
}

Greet({firstName: "John", lastName: "Smith"});

Notice how the object I pass in to the Greet function isn't explicit about what type it is. It merely mimics the structure defined in the interface. This is quite nifty I think.

As I also mentioned in my post from yesterday, TypeScript's type system allows for far better tooling support than we have been accustomed to up till now. Now don't get me wrong, the latest version of Visual Studio (2012) has become extremely good at handling JavaScript. But I think TypeScript will give us far more that what we have today. Statically typed JavaScript will give us far better support for refactoring our code, since the tool will know a lot more about the code up front. Also, IntelliSense (or other intelligent code-completion methods) will be much, much better. 

On the topic of Intellisense, one of the other majorly cool things is the external declaration file system. External declaration files allow us (or third-parties) to provide files that describe the internal structure of a library. This will give us true IntelliSense support for libraries like jQuery and Underscore. When instantiating jQuery, we have 8 different overloads to deal with. When using TypeScript, we will have much better control, since our tools will be able to tell what we're trying to do and thus only display the constructors (or other methods) that make sense at the time. 

The other thing that TypeScript provides us is class-based object orientation, as opposed to prototypal inheritance which can be quite confusing to people coming from the C# or Java worlds. Here's a silly little example that should demonstrate how classes and inheritance works, as well as the resulting JavaScript code.

class Vehicle {
	private numberOfWheels: number;
	constructor(noOfWheels: number) {
		this.numberOfWheels = noOfWheels;
	}
}

class Bycicle extends Vehicle {
	constructor() {
		super(2);
	}
}

And the resulting code: 

var __extends = this.__extends || function (d, b) {
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
}
var Vehicle = (function () {
    function Vehicle(noOfWheels) {
        this.numberOfWheels = noOfWheels;
    }
    return Vehicle;
})();
var Bycicle = (function (_super) {
    __extends(Bycicle, _super);
    function Bycicle() {
        _super.call(this, 2);
    }
    return Bycicle;
})(Vehicle);

Notice the __extends method that gets injected at the top. This is one of the only places where TypeScript injects code to your system that you didn't actually write yourself. It's used for some of the prototype plumbing that is needed to get the JavaScript objects to behave the way we want them to. Now a major advantage here is that the private keyword can be enforced by the compiler and thus help us by hiding inaccessible members. This really isn't possible in JavaScript. Also, as I pointed out yesterday, the class syntax is based on the official ECMAScript 6 proposal, and thus isn't something Microsoft have just pulled out of a magic hat. What this means is that once we get support for ECMAScript 6 (sometime in the distant future), the TypeScript compiler won't have to worry about compiling classes anymore. Neat!

Finally, TypeScript gives us support for JavaScript's module concept: 

module Utils {
	function Util1() {
		return "Hello World"
	}
}
// results in
var Utils;
(function (Utils) {
    function Util1() {
        return "Hello World";
    }
})(Utils || (Utils = {}));

So all in all I am pretty happy about what I see coming in TypeScript. I was pretty skeptical (to say the least) when I heard the announcement that Microsoft and Anders Hejlsberg were going to be giving us something "In the JavaScript tooling space". I must admit that I think TypeScript hits a nice sweet spot without becoming intrusive. I look forward to playing around a bit more with it and seeing how it affects my coding. The fact that TypeScript does a lot of type inference means that I can continue coding JavaScript like I normally do, but my tools and the compiler will be able to do a much better job of helping me out.

0 comments

I had the privilege of attending the ANUG User Group event at GOTO this afternoon, and there to present the latest addition to our web language toolbox, was Anders Helsberg. The topic of the talk was a new language called TypeScript. 


What is TypeScript?

TypeScript is at its core a language that enables enterprise-scale application development in JavaScript. Because it is a superset of JavaScript, TypeScript is JavaScript. We aren't being forced to re-learn all the things we already know about the language. 

Some of the key points I picked up from the talk are: 

  • TypeScript is a superset of JavaScript
  • Provides typed parameters 
    function greeter(person: string) {
        return "Hello, " + person;
    } 
  • Provides "interface types" 
    interface Person {
        firstname: string;
        lastname: string;
    }
    
    function greeter(person : Person) {
        return "Hello, " + person.firstname + " " + person.lastname;
    }
    
    var user = {firstname: "Jane", lastname: "User"};
  • Optional parameters
    function Greeter(name?: string) {
        ... 
    }
    
  • Class definitions
    class Greeter {
    	greeting: string;
    	constructor (message: string) {
    		this.greeting = message;
    	}
    	greet() {
    		return "Hello, " + this.greeting;
    	}
    }   
    
    var greeter = new Greeter("world");
     
  • At compile time, all type info is erased and thus you are left with pure JavaScript. The type info is used solely as a help to you and your tools during development time.
  • Type information for libraries like jQuery, underscore etc. is provided through type declaration files. A few are shipped with the product, and Microsoft expects that the community will be helpful in building declaration files for all the commonly used libraries. 
  • Class definitions are based on the ECMAScript 6 proposal
  • You can provide default values for parameters
  • Lexical scoping of the "this" keyword using the fat arrow (=>)
  • Supports the module concept
    module Sayings {
        export class Greeter {
            greeting: string;
            constructor (message: string) {
                this.greeting = message;
            }
            greet() {
                return "Hello, " + this.greeting;
            }
        }
    }
    results in this code:
    var Sayings;
    (function (Sayings) {
        var Greeter = (function () {
            function Greeter(message) {
                this.greeting = message;
            }
            Greeter.prototype.greet = function () {
                return "Hello, " + this.greeting;
            };
            return Greeter;
        })();
        Sayings.Greeter = Greeter;    
    })(Sayings || (Sayings = {}));
     
  • An important point is that the compiler never changes method bodies. They are left untouched. This means you don't have to worry that the compiler does things to your code that you don't expect. 

All in all I think this looks really exciting. I must admit I was a bit skeptical when I heard that Anders Hejlsberg was going to announce a new language that compiles to JS. My first thought was that this was either a new CoffeeScript or a new Dart. But in reality, this is neither of those two. This language provides us developers with some tools to help us with some of the "thousand paper cuts" that JavaScript development can be. For example, refactoring becomes a lot easier since the compiler is context-aware, and because Visual Studio continuously compiles the code in the background. This means we can rename variables without risking renaming the wrong ones. 

If you want to have a look at TypeScript, head over to http://typescriptlang.org and download it. And the best part is that it's open source under the Apache 2.0 License. 

0 comments

I've been invited to participate as a blogger at the GOTO Conference in Aarhus this October. Yay, that means more activity on this blog in the coming weeks/months!

Since I will be there "as a blogger", my main task will of course be to blog about the conference and about topics I find interesting or controversial. 

When attending conferences like this, one can chose to attend talks that are completely related to one's day-to-day work, or one can chose to attend talks that are a long way out of one's comfort zone. I haven't yet decided exactly which conference strategy I will be going for, but one thing is for sure: I'm definitely going for the chance to hang out (maybe have a beer?) with brilliant minds; to become inspired; to become wiser.

Stay tuned for more, I'll be writing another post or two before the conference, as soon the programme is finalized and I know more about which sessions I'm going to attend.

Feel free to check out the awesome speakers list on the website linked above and if you aren't going yourself but have a question you want answered, maybe I can be your proxy. Use the comments field below or send me an email (or Twitter) and I'll see what I can do.