TypeScript 1.5 Alphaに実装されたES6 modulesを試してみた

# はじめに
[Announcing TypeScript 1.5 Alpha - TypeScript - Site Home - MSDN Blogs](http://blogs.msdn.com/b/typescript/archive/2015/03/27/announcing-typescript-1-5-alpha.aspx) のように1.5のAlphaがリリースされました。
紹介されているES6 modulesは皆が期待しているものだと思うので、この機能に絞って試してみます。

この記事には直接は関係ないですが `npm install typescript`をすると現在1.5 Alphaがインストールされるので、1.4.1を入れたい方はバージョン指定しましょう。

# 環境
- Mac OS X Marveriks
- node 0.12.1
- TypeScript 1.5 Alpha

# ES6 modulesを試す
## サンプルコード
```ts:greet.ts
export function goodmorning(name: string) { return `Good morning, ${name}`; }
export function hello(name: string) { return `Hello, ${name}`; }
export function goodafternoon(name: string) { return `Good afternoon, ${name}`; }
export default function (name: string) { return `Hi!, ${name}`; }
```

```ts:main.ts
import {goodmorning, hello, goodafternoon} from "./greet";
import hi from "./greet";

console.log(goodmorning("TypeScript"));
console.log(hello("TypeScript"));
console.log(goodafternoon("TypeScript"));
console.log(hi("TypeScript"));
```

## パターン
コンパイル時のパターンは以下のようになります。

|番号| --target | --module |
| :--: | ------: | ------: |
| 1 | ES3 | commonjs |
| 2 | ES3 | amd |
| 3 | ES5 | commonjs |
| 4 | ES5 | amd |
| 5 | ES6 | commonjs |
| 6 | ES6 | amd |

### パターン1 (ES3 × commonjs)
`tsc --module commonjs main.ts greet.ts`

```js:greet.js
function goodmorning(name) { return "Good morning, " + name; }
exports.goodmorning = goodmorning;
function hello(name) { return "Hello, " + name; }
exports.hello = hello;
function goodafternoon(name) { return "Good afternoon, " + name; }
exports.goodafternoon = goodafternoon;
function default_1(name) { return "Hi!, " + name; }
exports.default = default_1;
```

```js:main.js
var greet_1 = require("./greet");
var greet_2 = require("./greet");
console.log(greet_1.goodmorning("TypeScript"));
console.log(greet_1.hello("TypeScript"));
console.log(greet_1.goodafternoon("TypeScript"));
console.log(greet_2.default("TypeScript"));
```

### パターン2 (ES3 × amd)
`tsc --module commonjs main.ts greet.ts`

```js:greet.js
define(["require", "exports"], function (require, exports) {
    function goodmorning(name) { return "Good morning, " + name; }
    exports.goodmorning = goodmorning;
    function hello(name) { return "Hello, " + name; }
    exports.hello = hello;
    function goodafternoon(name) { return "Good afternoon, " + name; }
    exports.goodafternoon = goodafternoon;
    function default_1(name) { return "Hi!, " + name; }
    exports.default = default_1;
});
```

```js:main.js
define(["require", "exports", "./greet", "./greet"], function (require, exports, greet_1, greet_2) {
    console.log(greet_1.goodmorning("TypeScript"));
    console.log(greet_1.hello("TypeScript"));
    console.log(greet_1.goodafternoon("TypeScript"));
    console.log(greet_2.default("TypeScript"));
});
```

### パターン3 (ES5 × commonjs)
`tsc --module commonjs --target ES5 main.ts greet.ts`

パターン1と同じ結果

### パターン4 (ES5 × amd)
`tsc --module amd --target ES5 main.ts greet.ts`

パターン2と同じ結果

### パターン5 (ES6 × commonjs), パターン6 (ES6 × amd)
`tsc --module commonjs --target ES6 main.ts greet.ts`

```bash
$ tsc --module commonjs --target ES6 main.ts greet.ts
error TS1204: Cannot compile external modules into amd or commonjs when targeting es6 or higher.
```
コンパイルエラーが出ました。amdでもたぶん出るんでしょうが叩いてみます。

`tsc --module amd --target ES6 main.ts greet.ts`

```bash
$ tsc --module amd --target ES6 main.ts greet.ts
error TS1204: Cannot compile external modules into amd or commonjs when targeting es6 or higher.
```

`--target ES6`の場合、`--module` のオプションをつけると怒られるようです。
素直に消してコンパイルしてみましょう。

`tsc --target ES6 main.ts greet.ts`

```js:greet.js
export function goodmorning(name) { return `Good morning, ${name}`; }
export function hello(name) { return `Hello, ${name}`; }
export function goodafternoon(name) { return `Good afternoon, ${name}`; }
export default function (name) { return `Hi!, ${name}`; }
```

```js:main.js
import { goodmorning, hello, goodafternoon } from "./greet";
import greet from "./greet";
console.log(goodmorning("TypeScript"));
console.log(hello("TypeScript"));
console.log(goodafternoon("TypeScript"));
console.log(hi("TypeScript"));
```

TypeScriptはES6の機能を実装しているので当たり前ですが、型情報がないだけのES6 modulesを使ったコードに落ち着きました。


# まとめ
予想していたとおりですが、ES3もしくはES5を指定した場合には`--module`で指定した形式に変換されるようでした。
なのでこれからは

- 内部モジュール + コンパイル時結合
- ES6モジュール
  - commonjs + Browserify( or webpack)
  - amd + RequireJS
  - ES6 modulesネイティブ(遙か未来?)
  
という選択肢になるのではないかと思います、たぶん。