JavaScript アドバンス

JS Modules エクスポート

1. export キーワード

モジュールでは、他のファイルと値を共有するために export キーワードを使用します。

  • 1つのモジュールに対して、複数の名前付きエクスポート(Named Export)を持つことができます。

1つのモジュールに対して、任意で1つだけのデフォルトエクスポート(Default Export)を持つことができます。

2. 名前付きエクスポート (Named Exports)

名前付きエクスポートでは、各アイテムに名前を付けて公開します。
アイテムは個別にエクスポートすることも、ファイルの末尾で { } にまとめてエクスポートすることも可能です。

2.1 個別にエクスポートする場合(person.js)

// 名前(name)と年齢(age)を個別にエクスポート
export const name = "Jesse";
export const age = 40;

2.2 末尾でまとめてエクスポートする場合(person.js)

const name = "Jesse";
const age = 40;

// 名前(name)と年齢(age)をまとめてエクスポート
export { name, age };

名前付きエクスポートをインポートする際は、{ } で囲む必要があります。また、名前が完全に一致していなければなりません。

2.3 インポート側の記述例

<script type="module">

// 名前(name)と年齢(age)をインポート
import { name, age } from "./person.js";

</script>

名前付きエクスポートは正しい命名を強制します。名前をスペルミスした場合はエラーになります。

2.4 実践的な例(math.js)

以下の例では、PIaddsubtractmultiplydivide がすべて名前付きエクスポートです。

export const PI = 3.14159;

export function add(a, b) {
  return a + b;
}
export function subtract(a, b) {
  return a - b;
}
export function multiply(a, b) {
  return a * b;
}
export function divide(a, b) {
  return a / b;
}

モジュールスクリプト:

<script type="module">

import { add, subtract, PI } from './math.js';

</script>

2.5 命名の厳格性

名前付きエクスポートでは、インポートする名前が正確に一致している必要があります。タイポや不用意なリネームによるミスを防ぐことができます。

import { calcluate } from './math.js'; // ❌ タイポによりエラーが発生

3. ツールボックス・ユーティリティ(ヘルパー)

複数のヘルパー関数を含むユーティリティモジュールには、名前付きエクスポートが最適です。

  • math.js
  • stringUtils.js
  • domHelpers.js
  • dateHelpers.js

名前付きエクスポートは、多くのユーティリティを詰め込んだ「ツールボックス」的なモジュールに非常に適しています。

3.1 ツリーシェイキング (Tree-Shaking)

名前付きエクスポートを利用することで、バンドラー(WebpackやViteなど)は使用されていないコードを削除するツリーシェイキング(Tree-shaking)を実行できるようになります。

以下の例では、PIsubtractmultiplydivide は最終的なビルドから削除されます。

import { add } from './math.js';

4. 名前付きエクスポートを使用すべきケース

ケース理由
多数の関数があるすべての関数を明確にリストアップできるため
厳格さが必要名前のタイポを未然に防げるため
大規模プロジェクト一貫性を向上させることができるため
ユーティリティセットモジュールの構造と一致しやすいため
ツリーシェイキング未使用のコードを自動的に削除できるため

5. デフォルトエクスポート (Default Exports)

デフォルトエクスポート(Default Export)は、モジュールから1つの主要な値をエクスポートするために使用します。これにより、そのモジュールのメインとなる機能が何であるかを明確に示すことができます。

ファイルが1つの主要な関数、クラス、または値を公開することを目的としている場合、デフォルトエクスポートはその意図を明示的にします。

export default function calculateSum() { ... }

       注意: 1つのファイルにつき、デフォルトエクスポートは1つだけです。

5.1 柔軟な命名

デフォルトエクスポートの利点は、インポート側で任意の名前を付けられることです。

import calc from './calculateSum.js';

calc という名前は、元の関数名と一致させる必要はありません。これに対し、名前付きエクスポートでは正確な一致が求められます。

import { calculateSum } from './calculateSum.js';

5.2 実践例(message.js)

モジュールファイル "message.js":

const message = () => {
  const name = "Jesse";
  const age = 40;
  return name + ' は ' + age + '歳です。';
};

export default message;

インポートパターン 1:

<script type="module">
import message from "./message.js";
</script>

インポートパターン 2(任意の名前を使用):

<script type="module">
import text from "./message.js";
</script>

5.3 クリーンなコード

多くのライブラリは、単一の機能をデフォルトとして公開しています。

import React from 'react';

6. デフォルト + 名前付きの併用

モジュールは、1つのメイン関数といくつかのヘルパー関数を組み合わせて提供することも可能です。

モジュールファイル:

// デフォルトエクスポート
export default function parse() { ... }

// 名前付きエクスポート
export function validate() { ... }
export function format() { ... }

モジュールスクリプト:

import parse, { validate, format } from './parser.js';

7. デフォルトエクスポートを使用すべきケース

ケース理由
主要な目的が1つメイン機能を持つモジュールに適しているため
柔軟な命名インポート側で名前を自由に選べるため
クリーンなインポートインポート構文がより短くシンプルになるため
一般的なパターン多くのフレームワークがメインAPIに採用しているため