JavaScriptのモジュールシステムを理解しよう – メリット・使い方・import方法などを解説

当サイトでは一部リンクに広告が含まれています
アイキャッチ

JavaScriptのモジュールシステムは、コードを整理し、再利用可能な部品(モジュール)に分けるための方法です。
この概念は、大規模なアプリケーションを作成する際に特に重要です。

今回は、より実践的なシステムを作るために必要なモジュールについて、初心者向けに丁寧に解説していきます。

目次

モジュールとは

プログラミングにおけるモジュールとは、独立した機能を持つコードのまとまりを指します。たとえば、数学的な関数を提供するモジュールや、日付と時刻に関連する関数を提供するモジュールなどがあります。

JavaScriptのモジュールシステムは、ECMAScript 6(ES6とも呼ばれます)というJavaScriptのバージョンで導入されました。これにより、JavaScriptコードを一つのファイルにまとめるのではなく、複数のファイル(モジュール)に分けることが可能になりました。

これにより、大規模なアプリケーションを開発する際でも、コードを綺麗に整理することができ、また一部のコードを再利用することも容易になりました。

モジュールの作成と利用:exportとimport

JavaScriptのモジュールシステムは、主に exportimport の2つのキーワードを使用します。

  • export: あるモジュールから特定の部品(関数、オブジェクト、値など)を公開(エクスポート)するためのキーワードです。
  • import: 他のモジュールから公開された部品を取り込む(インポート)するためのキーワードです。

これらのキーワードの使用方法を見ていきましょう。

utils.js

// 関数をエクスポート
export function sayHello(name) {
  console.log(`Hello, ${name}!`);
}

app.js

// 先ほどエクスポートした関数をインポート
import { sayHello } from './utils.js';

// 関数を使う
sayHello('World'); // 出力: "Hello, World!"

この例では、utils.jsという名前のモジュールがあります。このモジュールは sayHello という名前の関数をエクスポートしています。

そして、app.jsという別のモジュールがその関数をインポートしています。import文の中の{ sayHello }は、utils.jsからエクスポートされたsayHello関数を指しています。

名前付きエクスポートとデフォルトエクスポート

JavaScriptのモジュールシステムでは、2つの種類のエクスポートを使うことができます。それが名前付きエクスポートデフォルトエクスポートです。

名前付きエクスポート

名前付きエクスポートは、一つのモジュールから複数の値をエクスポートする時に使います。名前付きエクスポートされた値は、その名前でインポートすることができます。これを利用すると、一つのモジュールから複数の関数や値を公開することができます。

math.js

// 複数の関数をエクスポート
export function add(a, b) {
  return a + b;
}

export function subtract(a, b) {
  return a - b;
}

app.js

// 複数の関数をインポート
import { add, subtract } from './math.js';

console.log(add(1, 2)); // 出力: 3
console.log(subtract(5, 3)); // 出力: 2

上記の例では、math.jsというモジュールが2つの関数 addsubtract をエクスポートしています。そして、app.jsではこれらの関数をインポートし、使っています。

デフォルトエクスポート

デフォルトエクスポートは、一つのモジュールから一つの値(関数やオブジェクトなど)をエクスポートする際に使います。デフォルトエクスポートされた値は、インポートする際に任意の名前をつけることができます。

hello.js

// デフォルトエクスポート
export default function () {
  console.log('Hello, world!');
}

app.js

// デフォルトエクスポートをインポート
import greet from './hello.js';

greet(); // 出力: "Hello, world!"

上記の例では、hello.jsというモジュールが一つの関数をデフォルトエクスポートしています。この関数は名前を持っていません。そして、app.jsでは、そのデフォルトエクスポートされた関数をgreetという名前でインポートし、使用しています。

モジュールの利点とは

モジュールを使うことで、コードを再利用しやすくなり、ソースコードの管理も容易になります。大規模なアプリケーションを開発する際には、この利点が非常に大きくなります。

また、モジュールごとにコードを分けることで、どの部分のコードがどの機能を果たしているのかが明確になります。このため、バグを見つけやすくなったり、新しい機能を追加しやすくなったりします。

さらに、モジュールは独立してテストすることが可能です。そのため、ユニットテストを行う際にも役立ちます。

名前空間とスコープ

モジュールはそれぞれ独自のスコープを持ちます。これは、モジュール内で定義された変数や関数は、そのモジュール内だけで有効であり、他のモジュールから直接アクセスすることはできないということを意味します。

そのため、モジュールは名前空間を提供します。つまり、あるモジュール内で定義された関数や変数の名前が、他のモジュールで定義されたものと重複することはありません。

これにより、大規模なプロジェクトで複数の開発者が働いている場合でも、他の開発者が作成したモジュールの変数や関数の名前と衝突することを心配する必要がありません。

モジュールのリエクスポート

モジュールシステムの便利な機能の一つに、リエクスポートがあります。これは、あるモジュールが別のモジュールからインポートした値を、そのままエクスポートする機能です。

これを使うと、複数のモジュールからインポートした値をまとめて一つのモジュールからエクスポートすることができます。これにより、そのモジュールを使う側は、複数のモジュールから値をインポートする必要がなくなります。

以下に例を示します。

math.js

// 関数をエクスポート
export function add(a, b) {
  return a + b;
}

export function subtract(a, b) {
  return a - b;
}

string.js

// 関数をエクスポート
export function hello(name) {
  return `Hello, ${name}!`;
}

export function goodbye(name) {
  return `Goodbye, ${name}!`;
}

index.js

// math.jsとstring.jsから関数をインポートし、そのままエクスポート
export { add, subtract } from './math.js';
export { hello, goodbye } from './string.js';

app.js

// index.jsからすべての関数をインポート
import { add, subtract, hello, goodbye } from './index.js';

console.log(add(1, 2)); // 出力: 3
console.log(subtract(5, 3)); // 出力: 2
console.log(hello('World')); // 出力: "Hello, World!"
console.log(goodbye('World')); // 出力: "Goodbye, World!"

この例では、math.jsstring.jsという2つのモジュールがそれぞれ関数をエクスポートしています。そして、index.jsではそれらをインポートし、そのままエクスポートしています。

そして、app.jsではindex.jsからすべての関数をインポートしています。index.jsを通じてmath.jsstring.jsからエクスポートされたすべての関数にアクセスできます。

以上がJavaScriptのモジュールシステムについての基本的な説明です。この知識を持つことで、JavaScriptでの開発がより効率的になり、また大規模なアプリケーションの開発でもスムーズに進めることができるでしょう。

目次