import / export の基本

ES6(2015)で導入された ES Modules は、JavaScript の “モダンな書き方” を支える中心的な仕組みです。

その中核となるのが import / export です。

  • ファイルを分割して整理したい
  • 必要な機能だけを読み込みたい
  • グローバル汚染を避けたい
  • 再利用しやすいコードを書きたい

こうした目的のために、ES Modules は生まれました。

この回では、import / export の基本的な使い方を、実際のコード例を交えながら丁寧に解説します。


なぜ import / export が必要なのか

前回のモジュールスクリプトの基本で触れたように、従来の <script> にはいくつかの問題がありました。

  • すべてがグローバルスコープに置かれる
  • ファイル間の依存関係を明示できない
  • 読み込み順に強く依存する
  • 大規模化すると破綻しやすい

ES Modules は、これらの問題を解決するために設計されています。


export の基本

モジュールは、外部に公開したい機能を export することで、他のファイルから利用できるようになります。

export 方法には、大きく分けて下記の3つの記述方法があります。

1. 名前付きエクスポート(最も一般的)

export したい機能を個別に指定する方法です。

export function add(a, b) {
  return a + b;
}

export const PI = 3.14;

👉 複数の値を自由に export できます。

2. まとめてエクスポート

個別での export は行わず、最後にまとめて指定します。

function add(a, b) { return a + b; }
function sub(a, b) { return a - b; }

export { add, sub };

👉 export したい機能だけを後からまとめて記述するので、変更が容易です。


3. デフォルトエクスポート(1つだけ)

デフォルトの exportを指定します。(後述の import の記述方法が変わってきます。)

export default function greet(name) {
  console.log(`Hello, ${name}`);
}

👉 デフォルト export は、そのモジュール(ファイル)につき 1 つだけ 定義できます。

export の注意点

  • モジュールのトップレベルでしか使えない
  • 名前付き export は複数 OK
  • デフォルト export は 1 つだけ

import の基本

export された機能や値を別のファイルから import して利用します。

import の記述には、下記のような記述方法があります。

1. 名前付き import

名前付きエクスポートされたものをインポートする時に指定します。

math.js

export function add(a, b) {
  return a + b;
}

export const PI = 3.14;

main.js

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

👉 export された名前をそのまま使います。

2. 別名(エイリアス)をつける

名前付きエクスポートされたものをインポートする時に指定するものですが、他のモジュールとの名前の衝突を避けたい場合などに指定します。

math.js

export function add(a, b) {
  return a + b;
}

export const PI = 3.14;

main.js

import { add as plus } from "./math.js";

console.log(plus(1, 2));

👉 名前が衝突する場合に別名で定義できるので便利です。

3. デフォルト import

デフォルトエクスポートされたものを読み込む時に指定します。

greet.js

export default function greet(name) {
  console.log(`Hello, ${name}`);
}

main.js

import greet from "./greet.js";

greet("kon");

👉 デフォルト export{} を使いません。

4. 名前付き + デフォルトを同時に

デフォルトエクスポートされたものと名前付きエクスポートされたものを同時に読み込む時に指定します。

utils.js

export function add(a, b) {
  return a + b;
}

export const PI = 3.14;

export default function greet(name) {
  console.log(`Hello, ${name}`);
}

main.js

import greet, { add } from "./utils.js";

5. モジュール全体をまとめて import

モジュールに定義されている export をまとめて読み込みたい時に指定します。

math.js

export function add(a, b) {
  return a + b;
}

export const PI = 3.14;

main.js

import * as math from "./math.js";

math.add(1, 2);
math.PI;

👉 モジュールを1つの名前空間としてまとめたいときに便利です。

import のパスの注意点

import でスクリプトファイルを指定する際は、 URL として判断される為、パスとして指定する必要があります。又、ブラウザは拡張子を自動補完しない為、拡張子の省略も不可です。

import "./utils.js";      // OK
import "/scripts/app.js"; // OK
import "./math.js";       // OK

import "utils.js";        // NG(相対パスが必要)
import "./math";          // NG(拡張子が必要)


import / export の実行タイミング

ES Modules の大きな特徴は、import が静的に解析されるという点です。

■ import はトップレベルでしか使えない

if (true) {
  import "./a.js"; // ❌ エラー
}

👉 実行前に依存関係を確定する必要があるためです。

■ export もトップレベルのみ

モジュールの構造が明確になり、依存関係が静的に解析できます。


import / export の動作イメージ

┌──────────────────────────┐
│        math.js                                     │
│──────────────────────────│
│  const x = 100                                     │
│  export function add()                             │
│         function sub()                             │
│  export const PI                                   │
└─────────────┬────────────┘
                            │  import
                            ▼
┌──────────────────────────┐
│        main.js                                     │
│──────────────────────────│
│  import { add, PI }                                │
│  console.log(add(1, 2))                            │
└──────────────────────────┘

  • main.js が math.js を import
  • math.js が最初に 1 回だけ実行される
  • main.js は math.js の公開部分だけを利用できる
  • 変数はグローバルに漏れない

👉 モジュールは「安全な箱」
👉 必要なものだけを外に出す(export)
👉 必要なものだけを取り込む(import)


よくあるエラーと対処法

1. 「Cannot use import statement outside a module」

<script type="module"> を忘れている。

2. 「Failed to resolve module specifier」

→ パスが間違っている。(相対パス or 拡張子)

3. 「Unexpected token 'export'」

→ モジュールとして扱われていない。

4. CORS エラー

file:// で開いている。(ローカルサーバーが必要)


まとめ

  • import / export は ES Modules の中心機能
  • import / export には、用途に応じて、複数の記述方法がある
  • import / export はトップレベルでのみ使用可能
  • import において、パスと拡張子は必須
  • モジュールは 1 度だけ実行される
  • 小規模アプリならブラウザだけで十分、構造化したプログラミングが可能