ECMAScript 6/7 on the JVM with TypeScript and Vert.x

Fol­low­ing the latest re­lease of Vert.x 3.2 I’ve just up­loaded a new ver­sion of vertx-lang-typescript 1.1.0. The lib­rary adds TypeScript sup­port to Vert.x 3. TypeScript is a pro­gram­ming lan­guage that com­piles to JavaS­cript. It sup­ports the ECMAScript 6 (ECMAScript 2015, ES6) stand­ard and also a few parts of ECMAScript 7 (ES7) already.

vertx-lang-typescript auto­mat­ic­ally com­piles Vert.x verticles writ­ten in TypeScript to JavaS­cript and ex­ecutes them on the JVM. The lib­rary also provides type defin­i­tions for the Vert.x JavaS­cript API. Use them in your fa­vour­ite TypeScript ed­itor/​IDE to get auto-com­ple­tion, API doc­u­ment­a­tion and mean­ing­ful er­ror mes­sages (see screen­cast).

The latest re­lease of vertx-lang-typescript sup­ports TypeScript 1.7. I figured it would be a good idea to give you a couple of ex­amples how this new ver­sion helps you use ECMAScript 6 and 7 fea­tures on the JVM today.

ECMAScript 6/​7 and Vert.x

Be­low you find an ex­ample verticle writ­ten in TypeScript. Well, I left all the TypeScript-spe­cific parts out. In fact the verticle is valid ECMAScript 6 (ex­cept for the last snip­pet [9] which is ECMAScript 7).

First, fol­low the vertx-lang-typescript README to in­stall the lib­rary and to en­able TypeScript in Vert.x. Then ex­tract the type defin­i­tions (vertx-lang-typescript-1.1.0-typings.zip) into a new dir­ect­ory. Cre­ate a new file named es7verticle.ts in this dir­ect­ory and copy the code be­low into it. Fi­nally, open your com­mand prompt and ex­ecute

vertx run es7verticle.ts

This will run a small HTTP server that listens to re­quests on port 8080. If you open your browser and go to http://localhost:8080 you will see the fol­low­ing:

So far so good. Now let’s have a look at the code. I numbered the in­di­vidual ECMAScript fea­tures used. Here’s a com­plete list:

  1. Use an ar­row func­tion to cre­ate a re­quest hand­ler (ES6)
  2. Block-scoped vari­ables do not pol­lute your global namespace (ES6)
  3. Spe­cify a de­fault value for a func­tion para­meter (ES6)
  4. Use rest para­met­ers to col­lect mul­tiple para­met­ers in an ar­ray (ES6)
  5. Spread the con­tents of an ar­ray to func­tion para­met­ers (ES6)
  6. It­er­ate over ar­ray con­tents us­ing the for…of loop (ES6)
  7. tem­plate strings en­able string in­ter­pol­a­tion and multi-line strings (ES6)
  8. Use classes and in­her­it­ance (ES6)
  9. Use the new ex­po­nen­ti­ation op­er­ator as a short­cut for Math.pow() (ES7)
/// <reference path="./vertx-js/vertx.d.ts" />

// arrow functions ********************************************* [1]
vertx.createHttpServer().requestHandler(request => {
  // block-scoped variables (let keyword) ********************** [2]
  let response = request.response();
  response.setChunked(true);

  // default parameter ***************************************** [3]
  function send(msg = "NOOP") {
    response.write(msg);
  }
  send();
  send("\n");

  // rest parameters ******************************************* [4]
  function sendMulti(...messages) {
    messages.forEach(msg => response.write(msg));
  }
  sendMulti("Hello", " ", "World", "\n");

  // spread parameters ***************************************** [5]
  let messages = ["Foo", "Bar", "\n"];
  sendMulti(...messages);

  // for...of loop ********************************************* [6]
  let arr = ["1", "+", "1", "=", "2", "\n"];
  for (let v of arr) {
    send(v);
  }

  // multi-line template strings, string interpolation ********* [7]
  let name = "Elvis";
  send(`${name} lives
`);

  // classes *************************************************** [8]
  class Animal {
    eat() {
      send("Animal is eating\n");
    }
  }

  class Dog extends Animal {
    eat() {
      send("Dog is eating\n");
    }

    walk() {
      send("Dog is walking\n");
    }
  }

  class Bird extends Animal {
    eat() {
      super.eat();
      send("Animal is a bird\n");
    }

    fly() {
      send("Bird is flying\n");
    }
  }

  let dog = new Dog();
  let bird = new Bird();
  dog.eat();
  dog.walk();
  bird.eat();
  bird.fly();

  // exponentiation operator *********************************** [9]
  let i = 5 ** 2;
  send("" + i);
  send("\n");

  response.end();
}).listen(8080);

Conclusion

The ex­ample demon­strates very well how you can use ECMAScript 6 (and parts of 7) on the JVM today. In fact, there are a lot more cool ES6 fea­tures not in­cluded in the ex­ample such as con­stants (const), the prop­erty short­hand or method prop­er­ties.

TypeScript is so much more than just ES6. It ac­tu­ally has a very good static type sys­tem that al­lows you to make com­pile-time type checks. This is makes it much easier to write large Vert.x ap­plic­a­tions with many verticles. Per­son­ally I really like the sup­port that I get from my IDE when pro­gram­ming TypeScript. Since vertx-lang-typescript comes with type defin­i­tions for the Vert.x JavaS­cript API I get auto-com­ple­tion and ac­cess to the doc­u­ment­a­tion right in the ed­itor. I mostly use Sub­lime by the way, but I have tested it suc­cess­fully with Visual Stu­dio Code, Ec­lipse and Atom.

Un­for­tu­nately, the only ES7 fea­ture that you can use at the mo­ment with vertx-lang-typescript is the ex­po­nen­ti­ation op­er­ator. TypeScript 1.7 also sup­ports dec­or­at­ors but this fea­ture is dis­abled at the mo­ment in vertx-lang-typescript be­cause it is ex­per­i­mental and sub­ject to change. I’ll keep you up to date when new fea­tures are in­tro­duced.

Alternatives

Vert.x core de­veloper Paulo Lopes re­cently pub­lished a blog post on how to use ES6 with Vert.x. He uses Ba­bel, a com­piler that trans­lates ECMAScript 6 to 5.

Al­though this ap­proach works well it is a bit hard to set up and use for my taste. First, you need to wrap your Vert.x ap­plic­a­tion in a NPM pack­age. Second, in or­der to run your ap­plic­a­tion, you need to com­pile it with npm run build and then then call npm start.

I haven’t tested this ap­proach but I sup­pose the fact that you need to wrap your ap­plic­a­tion in a NPM pack­age does­n’t play well with build tools such as Gradle or Maven that you nor­mally would use for a Java pro­ject. Ad­di­tion­ally, you need to ex­ecute two com­mands to run your verticle. With vertx-lang-typescript you only need one. vertx-lang-typescript also al­lows you to em­bed the TypeScript verticle in a lar­ger Vert.x ap­plic­a­tion and also mix mul­tiple lan­guages in one pro­ject.

Fi­nally, the ap­proach based on Ba­bel only sup­ports ECMAScript 6 (2015), al­though more fea­tures from ES7 will surely be in­tro­duced in Ba­bel in the fu­ture. TypeScript on the other hand gives you much more fea­tures such as static typ­ing that you will cer­tainly find use­ful for any lar­ger pro­ject.


Posted by Michel Krämer
on December, 20th 2015.