とりあえず動く環境があり、構文も何となく理解したものの、複数ファイルに書いたとたんに動いてくれませんでした。今回はモジュールについての理解とまとめです。
この記事を書いた環境
tsc v1.6.2
でコンパイル・検証しています
参考にしたサイト
TypeScriptで複数ファイル構成する2つの方法
モジュール/Node.js/AMDなどを横断的に説明しているので分かりやすいです。
グローバルモジュール
referenceで参照する方法。d.ts
を取り込むだけではなくて本来は外部ファイルを参照するための方法らしい。
function f():string {
return 'test';
}
/// <reference path="./app.ts" />
f();
$ tsc app2.js --outFile out.js
コンパイル結果
function f() {
return 'f';
}
/// <reference path="./app.ts" />
f();
- 関数
f
がグローバル空間に展開される - このやり方は
jQuery
などの汎用的な外部ライブラリに使われる
内部モジュール
moduleを定義する方法。
namespaceでも可(ES6のmodule
と区別するためにこちらが推奨らしい)
module app {
export function f(): string {
return 'f';
}
}
/// <reference path="./app.ts" />
module app2 {
app.f();
}
$ tsc app2.js --outFile out.js
コンパイル結果
var app;
(function (app) {
function f() {
return 'f';
}
app.f = f;
})(app || (app = {}));
/// <reference path="./app.ts" />
var app2;
(function (app2) {
app.f();
})(app2 || (app2 = {}));
- 関数
f
が名前空間app
に展開される - グローバル空間を汚染しない
外部モジュール
簡単にまとめ
外部モジュールは機能を複数のファイルに分割し、それぞれをモジュールとして参照する仕組みの事。JavaScriptにはこの仕組みがないため、CommonJS
というAPI仕様が策定され、それをサポートする環境(Node.js)で使われるようになった。
ブラウザでモジュールが動作する仕組みはAMD
という別の仕様に切り離されている。WebPackやBrowserfyなどを使ってブラウザが解釈可能なJavaScriptに変換するか、RequireJSを使って実行時に変換する方法がある。
外部モジュール(CommonJS)
export/import/requireで参照を定義する。
export function f(): string {
return 'f';
}
import app = require('./app');
app.f();
commonjs
形式でコンパイル
$ tsc app2.ts --module commonjs --outDir dist
コンパイル結果
function f() {
return 'f';
}
exports.f = f;
var app = require('./app');
app.f();
-
exports/require
に置き換わる - Node.jsで使用できる
外部モジュール(AMD)
export/import/requireで参照を定義する。
export function f(): string {
return 'f';
}
import app = require('./app');
app.f();
amd
形式でコンパイル
$ tsc app2.ts --module amd --outDir dist
コンパイル結果
define(["require", "exports"], function (require, exports) {
function f() {
return 'f';
}
exports.f = f;
});
define(["require", "exports", './app'], function (require, exports, app) {
app.f();
});
-
exports/define
に置き換わる
RequireJSを使って読み込んでみる
<html>
<head>
<script type="text/javascript" data-main="js/app.js" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.22/require.js"></script>
</head>
</html>
import utils = require('./utils');
console.log(utils.f());
export function f(){
return 'test';
}
$ tsc app.ts --module amd --outDir dist
-
exports/define
がrequireJSによって解決されブラウザで動作するようになる
ES6 module
TypeScriptがサポートするES6 moduleの書き方もできる。
export default function (){
return 'f';
}
export function f1(){
return 'f1';
}
utils
を別名でインポートする
import * as u from './utils';
u.default();
u.f1();
f1()
をインポートする
import {f1} from './utils';
f1();