TypeScriptを使ってNode.jsとブラウザに対応したJSコード（UMD形式）を生成する


TypeScriptのソースコードをUMD形式のJavaScriptに生成することで、Node.jsとブラウザの両方に対応することができます。

（補足）[UMD (Universal Module Definition)](https://github.com/umdjs/umd)は、JavaScriptのモジュール形式の1つです。UMDは、AMDとCommonJSの両方をサポートしているため、Node.jsでもブラウザでも動かすこどができます。

## 前提
* Node.js、TypeScriptがインストールされていること。

## サンプル構成

```
% tree
.
├── README.md
├── index.html
├── package.json
├── src
│   ├── helloModule.ts
│   ├── index.ts
│   └── wordModule.ts
└── tsconfig.json
```

## TypeScriptソースコード

index.tsがNode.jsやブラウザから呼び出すエントリポイントです。helloModuleとwordModule（後述）をインポートし、メソッドを呼び出しています。

```src/index.ts
import {Hello} from './helloModule';
import {Word} from './wordModule'; 

Hello.say(); 
let word = new Word();
word.setWord('ES6');
console.log(word.getWord());
```

helloModuleの実装は以下のとおり。

```src/helloModule.ts
export class Hello {
    static say() {
        console.log('Hello TypeScript!');
    }
}
```

wordModuleの実装は以下の通り。

```src/wordModule.ts
export class Word {
	private word: string;
	
	setWord(word: string) {
		this.word = word;
	}
	
	getWord() {
		return this.word;
	}
}
```
    
## TypeScript設定

TypeScriptの設定ファイルを以下のように定義しておきます。moduleとして、"umd"を指定しています。

```tsconfig.json
{
  "compilerOptions": {
    "module": "umd",
    "target": "ES5",
    "noImplicitAny": true,
    "outDir": "./js"
  },
  "files": [
    "./src/helloModule.ts",
    "./src/wordModule.ts",
    "./src/index.ts"
  ]
}
```

## コンパイル

以下のコマンドで、TypeScriptのソースコードをES5なJavaScriptに変換します。

```
tsc -p .
```

変換結果はjsディレクトリに生成されています。

```
% ls js
helloModule.js  index.js        wordModule.js
```

（参考）index.tsの生成結果は以下のような形式です。

```js/index.js
(function (factory) {
    if (typeof module === 'object' && typeof module.exports === 'object') {
        var v = factory(require, exports); if (v !== undefined) module.exports = v;
    }
    else if (typeof define === 'function' && define.amd) {
        define(["require", "exports", './helloModule', './wordModule'], factory);
    }
})(function (require, exports) {
    "use strict";
    var helloModule_1 = require('./helloModule');
    var wordModule_1 = require('./wordModule');
    helloModule_1.Hello.say();
    var word = new wordModule_1.Word();
    word.setWord('ES6');
    console.log(word.getWord());
});
```


## Node.jsでの実行

Node.jsの設定ファイルを以下の様に記述してください。

```package.json
{
  "name": "ts-sample",
  "version": "1.0.0",
  "description": "",
  "main": "./js/index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
```

index.jsが実行され、helloModule.jsとwordModule.jsの関数が呼び出されています。

```
% node .
Hello TypeScript!
ES6
```

## ブラウザでの実行

以下のようなHTMLファイルを用意します。

```index.html
<html>
    <head>
        <script type="text/javascript" data-main="js/index.js"
        src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.22/require.js"></script>
    </head>
</html>
```

これをブラウザで開くと、コンソールに以下が出力されます。

```
Hello TypeScript! helloModule.js:14
ES6               index.js:15 
```

## 参考

* [mizdra's blog - Node.js始める→TypeScript始める](http://mizdra.hatenablog.com/entry/2015/12/15/191451)
* [TypeScript Compiler Options](http://www.typescriptlang.org/docs/handbook/compiler-options.html)
* [UMD (Universal Module Definition)](https://github.com/umdjs/umd)