LoginSignup
48

More than 3 years have passed since last update.

TypeScript超入門(3):モジュール

Last updated at Posted at 2016-01-09

とりあえず動く環境があり、構文も何となく理解したものの、複数ファイルに書いたとたんに動いてくれませんでした。今回はモジュールについての理解とまとめです。

この記事を書いた環境

tsc v1.6.2でコンパイル・検証しています

参考にしたサイト

TypeScriptで複数ファイル構成する2つの方法
モジュール/Node.js/AMDなどを横断的に説明しているので分かりやすいです。

グローバルモジュール

referenceで参照する方法。d.tsを取り込むだけではなくて本来は外部ファイルを参照するための方法らしい。

app.ts
function f():string {
    return 'test';
}
app2.ts
/// <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と区別するためにこちらが推奨らしい)

app.ts
module app {
    export function f(): string {
        return 'f';
    }
}
app2.ts
/// <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という別の仕様に切り離されている。WebPackBrowserfyなどを使ってブラウザが解釈可能なJavaScriptに変換するか、RequireJSを使って実行時に変換する方法がある。

外部モジュール(CommonJS)

export/import/requireで参照を定義する。

app.ts
export function f(): string {
    return 'f';
}
app2.ts
import app = require('./app');
app.f();

commonjs形式でコンパイル

$ tsc app2.ts --module commonjs --outDir dist

コンパイル結果

app.js
function f() {
    return 'f';
}
exports.f = f;
app2.js
var app = require('./app');
app.f();
  • exports/requireに置き換わる
  • Node.jsで使用できる

外部モジュール(AMD)

export/import/requireで参照を定義する。

app.ts
export function f(): string {
    return 'f';
}
app2.ts
import app = require('./app');
app.f();

amd形式でコンパイル

$ tsc app2.ts --module amd --outDir dist

コンパイル結果

app.js
define(["require", "exports"], function (require, exports) {
    function f() {
        return 'f';
    }   
    exports.f = f;
});
app2.js
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>
app.ts
import utils = require('./utils');

console.log(utils.f());
utils.ts
export function f(){
    return 'test';
}
$ tsc app.ts --module amd --outDir dist
  • exports/defineがrequireJSによって解決されブラウザで動作するようになる

ES6 module

TypeScriptがサポートするES6 moduleの書き方もできる。

utils.ts
export default function (){
    return 'f';
}
export function f1(){
    return 'f1';
}

utilsを別名でインポートする

app.ts
import * as u from './utils';
u.default();
u.f1();

f1()をインポートする

app.ts
import {f1} from './utils';
f1();

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
48