名前空間インポート(import *)

import * as 構文を使うと、モジュールのすべてのエクスポートを1つのオブジェクト(名前空間)としてインポートできます。

基本的な使い方

import * as 名前 from の形式で、すべてのエクスポートを含むオブジェクトを取得します。

// math.js
export const PI = 3.14159;
export const E = 2.71828;

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

export function multiply(a, b) {
  return a * b;
}
// main.js
import * as math from './math.js';

console.log(math.PI);          // 3.14159
console.log(math.E);           // 2.71828
console.log(math.add(2, 3));   // 5
console.log(math.multiply(2, 3)); // 6

デフォルトエクスポートへのアクセス

名前空間オブジェクトからデフォルトエクスポートにアクセスするには、default プロパティを使用します。

// greet.js
export default function(name) {
  return `Hello, ${name}!`;
}

export const VERSION = "1.0";
// main.js
import * as greet from './greet.js';

console.log(greet.default("田中")); // "Hello, 田中!"
console.log(greet.VERSION);         // "1.0"

通常のインポートとの比較

名前付きインポート

必要なものだけを選んでインポート。何を使っているか明確。

名前空間インポート

すべてをまとめてインポート。名前空間でグループ化される。

// 名前付きインポート
import { add, multiply, PI } from './math.js';
add(1, 2);

// 名前空間インポート
import * as math from './math.js';
math.add(1, 2);

名前空間インポートの利点

名前の衝突を回避

複数のモジュールに同じ名前の関数がある場合、名前空間で区別できます。

所属が明確

math.add() のように、どのモジュールの関数か一目で分かります。

import * as stringUtils from './stringUtils.js';
import * as arrayUtils from './arrayUtils.js';

// どちらのモジュールの関数か明確
stringUtils.format(text);
arrayUtils.format(items);

実際の使用例

外部ライブラリを名前空間インポートするパターンはよく見られます。

// React の場合
import * as React from 'react';
const element = React.createElement('div', null, 'Hello');

// より一般的な書き方
import React, { useState, useEffect } from 'react';
// Lodash の場合
import * as _ from 'lodash';
_.chunk([1, 2, 3, 4], 2);

// 特定の関数だけ使う場合
import { chunk, flatten } from 'lodash';

注意点

名前空間インポートは便利ですが、いくつかの点に注意が必要です。

Tree Shaking が効きにくい場合がある
すべてをインポートするため、何を使っているか分かりにくくなる可能性
大きなモジュールでは不要なコードもバンドルに含まれることがある
// Tree Shaking の観点では、名前付きインポートの方が良い
import { add } from './math.js'; // add だけバンドルされる

// 名前空間インポートだと全部含まれる可能性
import * as math from './math.js'; // 最適化されない場合がある

小さなユーティリティモジュールや、明確に区別したい複数のモジュールを扱う場合に名前空間インポートは効果的です。大規模なライブラリでは、必要なものだけを名前付きインポートする方がバンドルサイズの最適化に有利です。