script type="module" の使い方
ブラウザで ES Modules を使用するには、script タグに type="module" 属性を追加します。これにより、ブラウザはスクリプトをモジュールとして扱い、import/export 構文を解釈できるようになります。
基本的な使い方
<!-- モジュールとして読み込む -->
<script type="module" src="main.js"></script>// main.js
import { greet } from './utils.js';
console.log(greet('World'));インラインモジュール
外部ファイルだけでなく、HTML 内に直接モジュールのコードを書くこともできます。
<script type="module">
import { format } from './utils.js';
console.log(format(new Date()));
</script>通常のスクリプトとの違い
| 特徴 | 通常のスクリプト | type="module" |
|---|---|---|
| 実行タイミング | 即座に実行 | defer と同様 |
| スコープ | グローバル | モジュールスコープ |
| 厳格モード | 任意 | 自動適用 |
| this | window | undefined |
defer と同様の動作
モジュールは、HTML のパース完了後に実行されます。これは defer 属性と同じ動作です。
<!-- これらは同じタイミングで実行される -->
<script type="module" src="module.js"></script>
<script defer src="script.js"></script>通常のスクリプト
HTML のパースをブロックして即座に実行
type="module"
HTML パース完了後に実行(defer 相当)
複数回の読み込み
同じモジュールを複数回指定しても、実際に読み込まれるのは1回だけです。
<script type="module" src="utils.js"></script>
<script type="module" src="utils.js"></script>
<!-- utils.js は1回だけ実行される -->crossorigin 属性
モジュールはデフォルトで CORS(Cross-Origin Resource Sharing)リクエストとして扱われます。同一オリジンでない場合は、サーバー側で適切な CORS ヘッダーを設定する必要があります。
<!-- 外部ドメインからのモジュール -->
<script type="module" src="https://cdn.example.com/lib.js" crossorigin></script>async 属性との併用
モジュールでも async 属性を使用できます。この場合、モジュールが読み込まれ次第、即座に実行されます。
<!-- 読み込み完了次第、すぐに実行 -->
<script type="module" async src="analytics.js"></script>async なし
すべてのモジュールが読み込まれ、HTML パース完了後に順番に実行。
async あり
読み込みが完了したモジュールから順に実行。実行順序は保証されない。
MIME タイプ
サーバーは JavaScript ファイルを正しい MIME タイプで配信する必要があります。
ファイルパスの指定
ブラウザでのモジュール指定では、相対パスには ./ または ../ が必要です。
// 正しい
import { func } from './utils.js';
import { helper } from '../lib/helper.js';
// エラー(ブラウザでは裸の指定子は使えない)
import { func } from 'utils.js';実行例
<!DOCTYPE html>
<html>
<head>
<title>ES Modules Demo</title>
</head>
<body>
<h1>Hello Modules</h1>
<script type="module">
import { message } from './message.js';
document.querySelector('h1').textContent = message;
</script>
</body>
</html>type="module" を使用することで、ビルドツールなしでもブラウザで直接 ES Modules を利用できます。