[JavaScript] import と export の使い方と仕様を理解する

7 min read

ES Modules の使い方

主にフロントエンド(クライアント)で用いられるファイルの読み込み方法である ES Modules について解説する。ES Modules は ES6 で追加された機能であり、古いブラウザでは動作しない場合がある。

importの使い方

importは、ほかの .js.ts ファイルを読み込むための機能であり、CommonJS のrequire()と同等の役割を果たす。しかし、基本的なimport構文は、require()とは異なり、ファイルの最上部に記述する必要がある。

以下に使用例を示す。

import * as package1 from 'package1';
import package2 from 'package2';
import { package3 } from 'package3';

アスタリスク(*)を使ったimport

* を使って import すると、exportされている変数や関数を一度にインポートし、package1 オブジェクトとしてアクセスすることが可能になる。

例えば、package1 モジュールが関数 foobar をエクスポートしている場合、以下のように利用できる。

import * as package1 from 'package1';

package1.foo();
package1.bar();

dynamic import

ES6 からはimport()という形式のdynamic importも導入されている。このdynamic importは、モジュールを非同期に読み込むための機能で、ファイルの任意の位置、つまりファイルの最上部に記述する必要はない。これにより、条件付きのモジュール読み込みや、パフォーマンスを向上させるための遅延ロード等が可能となっている。

なお、この dynamic import はPromiseを返すため、非同期処理の管理にはasync/await.then()を用いる。

exportの使い方

exportは CommonJS のmodule.exportsに相当する機能であり、記述方法はdefault exportnamed exportと呼ばれる 2 つがある。

// `default export`
export default (i) => i + 1;

// `named export`
export const increment = (i) => i + 1;

default exportの使い方

まず、exportするファイルで以下のように記述する。

const increment = (i) => i + 1;

export default increment;

次にモジュールを利用するファイルで以下のように記述する。

import increment from './util';

console.log(increment(3)); // -> 4

named exportの使い方

まず、exportするファイルで以下のように記述する。

const increment = (i) => i + 1;

export { increment };

次にモジュールを利用するファイルで以下のように記述する。

import { increment } from './util';

console.log(increment(3)); // -> 4

// or

import * as util from './util';

console.log(util.increment(3)); // -> 4

importで名前を変更する場合、requireとは異なりasという表記を用いて変更する。
この例ではconstで定数宣言をしているが、letを用いても読み込み側からincrementの定義を書き換えることはできない。

import { increment as inc } from './util';

console.log(inc(3)); // -> 4

default exportnamed export の違い

default exportの利点と欠点

  • default exportの利点:
    • importする際に名前を自由に変更可能である
    • 提供したい主要な機能が何であるかを、ほかのexportと比較して明確に示すことができる
  • default exportの欠点:
    • 使用するエディタや IDE によっては、コードの補完が期待するほど効かないことがある
    • 再エクスポートする際には名前を明示的に指定する必要がある

named exportの利点と欠点

  • named exportの利点:
    • エディタや IDE のコード補完が有効に機能する
    • ひとつのファイルから複数の要素をexportできる
  • named exportの欠点:
    • 名前の変更は可能だが、基本的には定義された名前でimportし利用することが求められる
    • exportしているファイルが名前を変更すると、それに依存するコードが動作しなくなる

比較

以下の表は、default exportnamed exportの主要な特徴である。

機能default exportnamed export
名前のフレキシビリティ(インポート時に名前を変えられる)
主要機能の明確化
エディタや IDE によるコード補完
複数エンティティのエクスポート
再エクスポート時の命名必要性
名前の変更による影響

ロジックが変化し、その変化に対応する修正を強制したい場合は、named exportが有用である。エディタや IDE を利用して特定のエクスポートを容易に探すことが可能である。一方、API が一貫性を持ち明瞭であるような公開パッケージの場合、default exportが価値を持つ。

結局のところ、選択はプロジェクトの要件や開発チームの方針による。default exportであろうとnamed exportであろうと、一貫性を保つことでコードの可読性や保守性を向上させることが可能である。