今回はTypeScriptにおけるモジュール、その中でも内部モジュールについて解説したいと思います。TypeScriptで複数のファイル構成を扱う際は、非常に重要な概念になってくるのでぜひこの機会に理解を深めましょう。

そもそもモジュールとは
モジュールとは、あるまとまりを持った機能単位のことを指します。モジュールに分割して開発を進めることで、コードの保守や再利用がしやすくなるという利点があります。
IT用語辞典には、モジュールの説明が以下のように書かれています。
モジュール(英:module)とは「部品」のこと。
もう少し、いろいろ書くと「そいつ単独でも機能としては成立するけど、普通は他のものと組み合わせて使うよ!」な部品のことです。
参考:https://wa3.i-3-i.info/word12243.html
TypeScriptでのモジュールの役割
TypeScriptを含めた様々なプログラミング言語では、モジュールを使うことで共通のコードを複数ファイルで分割して管理することができます。
例えば以下のメソッドを複数のページで使いたいとします。
その場合は以下のコードを別ファイルに切り出し、使いたいページで呼び出すという手法を使います。これがモジュールの役割になります。
function multi(x: number, y: number): number{
return x * y
}
グローバルモジュールとは
内部モジュールと外部モジュールを学習する上で、グローバルモジュールについての知識は必須なので先に解説しておきます。
とは言っても、目新しい知識は全くありません。
普段みなさんが使っているメソッドや変数は全てグローバルモジュールになります。
例えば以下のコードを「sample.ts」というファイルに記載しました。
↓ sample.ts
function multi(x: number, y: number): number{
return x * y
}
続いて、新たに「test.ts」という名前のファイルを作成し、先ほどのメソッドを呼び出す記述をしました。
↓ sample.ts
/// <reference path="./test.ts" />
console.log(multi(5, 3))
ここでコンパイルを実行すると、エラーが出ることなく期待される結果が出力されると思います。このように、どこからでも変数やメソッドを呼び出すことができるモジュールをグローバルモジュールと呼びます。
% tsc test.ts --out all.js
% node all.js
=> 15
TypeScriptでとあるコードを記述すると、デフォルトでグローバル空間に追加されます。
例えば「sample1.ts」で以下のコードを記述したとします。
var test1 = "アイウエオ";
続いて「sample2.ts」を作成し、先程定義した変数test1を使う記述をしても正常に動作します。
var test2 = test1;
このようにコードがグローバル空間にあることで、どこからもその値を呼び出すことができます。しかし一方で、グローバル空間を使うことで名前が競合する危険があるということを覚えておきましょう。
内部モジュールとは
ではここからが本題です。
内部モジュールとは、共通のメソッドや変数をグローバル空間に記載したくない場合に用いられる手法です。モジュールのデータを参照する場合は「export」を記述し、外部に公開しなくてはなりません。
内部モジュールの記述方法について見ていきましょう。
モジュールを作りたい場合は、moduleキーワードを使用しモジュール名を記載します。
module TestModule {
}
そこに管理したいメソッドや変数などを入れます。今回は数値を変数で管理します。
module TestModule {
export var price = 300;
}
モジュールは入れ子構造にすることも可能なので、もう1つモジュールを追加してみます。
module TestModule {
export var price = 300;
export module SampleModule {
export var item = "ショートケーキ"
}
}
ではこれらのデータにアクセスしてみましょう。モジュールにアクセスするにはモジュール名にドット(.)を付ける必要があります。
module TestModule {
export var price = 300;
export module SampleModule {
export var item = "ショートケーキ"
}
}
console.log(TestModule.price);
=> 300
console.log(TestModule.SampleModule.item);
=> ショートケーキ
「import」を使用することで、入れ子構造にしたモジュールを以下のように短く記載することも可能です。
module TestModule {
export var price = 300;
export module SampleModule {
export var item = "ショートケーキ"
}
}
import merge = TestModule.SampleModule;
console.log(TestModule.price);
=> 300
console.log(merge.item);
=> ショートケーキ
モジュールの切り出し
モジュールの記述量が増えてきた場合は、別ファイルに切り出すことも可能です。
先ほど記述していたファイル名を「test.ts」とし、切り出すファイル名を「sample.ts」としました。以下のようにモジュールを切り出しましょう。
↓ test.ts
console.log(TestModule.price);
console.log(TestModule.SampleModule.item);
↓ sample.ts
module TestModule {
export var price = 300;
export module SampleModule {
export var item = "ショートケーキ"
}
}
このままコンパイルを実行してもモジュールを呼び出すことはできません。
その場合は、以下のように「reference」を使用して呼び出す必要があります。こうすることで「test.ts」をコンパイルすると、「sample.ts」も自動でコンパイルしてくれるようになります。
↓ test.ts
/// <reference path="./sample.ts" />
console.log(TestModule.price);
console.log(TestModule.SampleModule.item);
最後にコンパイルを実行して完了なのですが、ただコンパイルした場合は「test.js」と「sample.js」の2ファイルができてしまいます。
その場合は「outオプション」をコンパイルコマンドに付与することで1つのファイルに集約することができます。今回は「all.js」というファイルに集約することにします。
% tsc test.ts --out all.js
% node all.js
まとめ
- モジュールとは、あるまとまりを持った機能単位のことを指す。
- モジュールに分割して開発を進めることでコードの保守や再利用がしやすくなる。
- グローバルモジュールとは、どこからでも変数やメソッドを呼び出すことができるモジュールである。
- TypeScriptでとあるコードを記述すると、デフォルトでグローバル空間に追加される。
- 内部モジュールとは、共通のメソッドや変数をグローバル空間に記載したくない場合に用いられる手法である。
- モジュールのデータを参照する場合はexportを記述する。
- モジュールは入れ子構造にすることもできる。
- モジュールにアクセスするにはモジュール名にドット(.)を付ける。
- モジュールを別ファイルに切り出した場合はreferenceで呼び出す必要がある。
- referenceを使用するには「///」という特殊なコメントを使用する。
- outオプションを付与することで1つのファイルに集約することができる。
参考
「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典:
https://wa3.i-3-i.info/word12243.html
ファイルモジュール:
https://typescript-jp.gitbook.io/deep-dive/project/modules
TypeScript超入門(3):モジュール:
https://qiita.com/ringtail003/items/f7ed257c86e5522f6e59
TypeScriptで複数ファイル構成する2つの方法:
https://teppeis.hatenablog.com/entry/2014/05/typescript-external-modules
今回はTypeScriptにおけるモジュール、その中でも内部モジュールについて解説しました。モジュールを使用することで、保守性や管理のしやすさが向上することは明確でしたね。モジュールが使えるコードでは積極的に使用するようにしましょう。
外部モジュールについてはこちら
