第18章 モジュール
モジュールとは?
JavaScriptのモジュールは、関連する関数、変数、クラスなどを一つのファイルにまとめたものです。モジュールを使用することで以下のような利点が得られます。
- 再利用性: モジュールは再利用可能なコードの単位となります。一度作成したモジュールを、異なるプロジェクトやアプリケーションで再利用することができます。
- 名前空間: 変数や関数などの名前が他のコードと衝突することを防ぐことができます。モジュール内で定義された変数や関数は、エクスポートされない限りそのモジュール内でのみ有効です。これにより、グローバルスコープの汚染を避けることができます。
- メンテナンス: コードをモジュールに分割することで、各モジュールが持つ役割や機能が明確になります。これにより、コードのメンテナンスやデバッグが容易になります。
- 遅延評価: ES6モジュールは、インポートされるまで評価(実行)されません。これにより、アプリケーションの起動時間を短縮することができます。
ES6モジュールの基本
export: 外部からアクセスできるようにするためのキーワード。
// math.js
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;
import: 他のモジュールで定義されている機能を利用するためのキーワード。
// app.js
import { add, subtract } from './math.js';
console.log(add(5, 3)); // 8
console.log(subtract(5, 3)); // 2
デフォルトエクスポートと名前付きエクスポート
デフォルトエクスポート: モジュールごとに1つだけ定義できるエクスポート。
// greeter.js
export default function greet(name) {
return `Hello, ${name}!`;
}
名前付きエクスポート: 複数のエクスポートを1つのモジュールから行う。
// math.js
export const multiply = (a, b) => a * b;
export const divide = (a, b) => a / b;
エイリアスを使ったインポート
// module.js
export const foo = "bar";
import { foo as myFoo } from './module.js';
console.log(myFoo); // "bar"を出力
全てのエクスポートをインポートする
// module.js
export const foo = "bar";
import * as myModule from './module.js';
console.log(myModule.foo); // "bar"を出力
HTML上で読み込む
モジュールをHTML上で読み込む際には、<script>タグのtype属性をmoduleとして指定します。
<script type="module" src="./main.js"></script>
スコープとは?
スコープとは、変数や関数などの識別子が参照できる範囲のことを指します。JavaScriptには主に3つのスコープがあります。
- グローバルスコープ: スクリプトのどこからでも参照できるスコープです。変数はデフォルトでグローバルスコープに属します(ただし、let、const、classを使用して宣言された変数は除く)。
- 関数スコープ: functionキーワードを使用して宣言された関数内でのみ参照できるスコープです。varキーワードで宣言された変数は関数スコープになります。
- ブロックスコープ: {}(波括弧)で囲まれた部分、例えばif文やforループ内部のスコープです。let、const、classで宣言された変数はブロックスコープに属します。
モジュールとスコープ
モジュールが導入されると、モジュール自体が独自のスコープを持つようになりました。これは、モジュール内で宣言された変数や関数は、そのモジュール内でのみ参照できるということを意味します。外部からアクセスしたい場合、それらの変数や関数を明示的にエクスポートする必要があります。
// module.js
let privateVar = "私はモジュール内のみ参照可能です";
export let publicVar = "私はエクスポートされたので外部からも参照可能です";
上記の例では、privateVarはモジュール内部でのみアクセス可能で、publicVarはエクスポートされているので、このモジュールをインポートする他のモジュールからもアクセスできます。
注意点
- 非同期読み込み: <script type="module">はデフォルトでdefer属性が指定されているとみなされ、ドキュメントの解析が完了してから実行されます。
- CORS: モジュールスクリプトはCORS(Cross-Origin Resource Sharing)チェックに従います。異なるオリジンからモジュールを読み込む場合、適切なCORSヘッダが必要です。
- MIMEタイプ: サーバーから返されるモジュールスクリプトのMIMEタイプは、application/javascriptである必要があります。
練習問題1.
・mathFunctions.jsというモジュールを作成し、その中に足し算と引き算を行う2つの関数を定義してください。
・それらの関数をエクスポートして、main.jsという別のファイルでインポートして利用してください。
練習問題2.
・person.jsというモジュールを作成し、その中にPersonというクラスを定義してください。クラスには、名前と年齢を引数とするコンストラクタと、自己紹介を行うメソッドを追加してください。
・このクラスをデフォルトエクスポートし、main.jsでインポートして、新しいPersonオブジェクトを作成して自己紹介メソッドを実行してください。
練習問題3.
・shapes.jsというモジュールを作成し、その中にSquareとCircleの2つのクラスを定義してください。それぞれのクラスには、面積を計算するメソッドを実装してください。
・main.jsでshapes.jsから2つのクラスをインポートしますが、SquareクラスはMySquareというエイリアスでインポートしてください。そして、それぞれのクラスを使用して面積を計算してください。