Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
44
Help us understand the problem. What is going on with this article?
@ringtail003

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

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

この記事を書いた環境

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();
44
Help us understand the problem. What is going on with this article?
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
ringtail003
フロントエンドエンジニアのお仕事をしています。技術本を高校生の息子に買わせる貧乏人。TypeScriptとAngularが好きです。
quartetcom
リスティング広告運用総合支援ツール「Lisket」を開発・運営しています。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
44
Help us understand the problem. What is going on with this article?