インポートマップ(Import Maps)

Import Maps(インポートマップ)は、ブラウザでモジュール指定子をどの URL に解決するかを定義する機能です。これにより、裸の指定子(bare specifier)を使ったり、パッケージのバージョン管理を行ったりできます。

裸の指定子の問題

通常、ブラウザでは以下のような裸の指定子は使用できません。

// ブラウザでは通常エラーになる
import React from 'react';
import { format } from 'date-fns';

Node.js では node_modules から解決されますが、ブラウザにはその仕組みがありません。

Import Maps の基本

Import Maps を使うと、裸の指定子を特定の URL にマッピングできます。

<script type="importmap">
{
  "imports": {
    "react": "https://esm.sh/react@18.2.0",
    "react-dom": "https://esm.sh/react-dom@18.2.0"
  }
}
</script>

<script type="module">
  import React from 'react';
  import ReactDOM from 'react-dom';
  
  // 通常通り使える
  console.log(React.version);
</script>

マッピングの種類

<script type="importmap">
{
  "imports": {
    "lodash": "https://cdn.example.com/lodash.js",
    "utils": "./src/utils.js",
    "components/": "./src/components/"
  }
}
</script>
パターン説明
"lodash"完全一致、単一モジュール
"components/"プレフィックスマッチ、フォルダ全体
// 完全一致
import _ from 'lodash';

// プレフィックスマッチ
import { Button } from 'components/Button.js';
// → ./src/components/Button.js に解決される

スコープによる条件付きマッピング

特定のモジュールからインポートする場合に、異なるマッピングを適用できます。

<script type="importmap">
{
  "imports": {
    "lodash": "https://cdn.example.com/lodash-v4.js"
  },
  "scopes": {
    "/legacy/": {
      "lodash": "https://cdn.example.com/lodash-v3.js"
    }
  }
}
</script>

/legacy/ ディレクトリ内のモジュールは Lodash v3 を使用し、他は v4 を使用します。

バージョン管理

同じライブラリの異なるバージョンを共存させることができます。

<script type="importmap">
{
  "imports": {
    "lodash-v3": "https://cdn.skypack.dev/lodash@3",
    "lodash-v4": "https://cdn.skypack.dev/lodash@4"
  }
}
</script>

<script type="module">
  import _ from 'lodash-v4';
  // 新しいコードは v4 を使用
</script>

CDN との連携

ES Modules 対応の CDN と組み合わせると、npm パッケージをそのまま使用できます。

esm.sh

npm パッケージを ES Modules として配信。TypeScript もサポート。

Skypack

npm パッケージの ESM 版を提供。最適化されたバンドルを配信。

<script type="importmap">
{
  "imports": {
    "three": "https://esm.sh/three@0.160.0",
    "three/addons/": "https://esm.sh/three@0.160.0/examples/jsm/"
  }
}
</script>

<script type="module">
  import * as THREE from 'three';
  import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
</script>

注意点

Import Maps は最初のモジュール読み込み前に定義する必要がある
1ページに1つの importmap のみ使用可能
動的に変更することはできない
一部の古いブラウザではサポートされていない

ポリフィル

古いブラウザ向けには、es-module-shims というポリフィルがあります。

<!-- Import Maps ポリフィル -->
<script async src="https://ga.jspm.io/npm:es-module-shims@1.8.0/dist/es-module-shims.js"></script>

<script type="importmap">
{
  "imports": {
    "react": "https://esm.sh/react@18"
  }
}
</script>

Import Maps を活用することで、バンドラーなしでも npm パッケージを直接ブラウザで使用でき、シンプルなプロジェクトやプロトタイピングに便利です。