Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

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

この記事を書いた環境

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();
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした