TTIL

2022-01-02 JavaScript モジュール / export

JavaScript モジュール - JavaScript | MDN

例えば下記のような構成で js ファイルがあるとする。

index.html
main.js
modules/
    square.mjs

これを JavaScript モジュール として読み込む場合、下記のようにする。

Load script

<script type="module" src="main.js"></script>

type="module" がミソ。

export & import

// square.mjs
export const name = 'square';
// main.js
import { name } from './modules/square.mjs';

mjs vs js

この記事ではモジュールファイルに .js の拡張子を使用していますが、他の記事では .mjs という拡張子が使用されているのを目にすることがあるかもしれません。例えば、V8 のドキュメントではこれを推奨しています。理由は以下の通りです。

  • どのファイルがモジュールで、どのファイルが通常の JavaScript であるかを明確にすることができます。
  • これにより、Node.js のようなランタイムや Babel のようなビルドツールで、モジュールファイルがモジュールとして解析されるようになります。

しかし、少なくとも今のところは .js を使い続けることにしました。ブラウザでモジュールを正しく動作させるためには、サーバーが text/javascript などの JavaScript MIME タイプを含む Content-Type ヘッダでモジュールを提供していることを確認する必要があります。そうしないと、”The server responded with a non-JavaScript MIME type” のような厳格な MIME タイプチェックエラーが表示され、ブラウザは JavaScript を実行しません。ほとんどのサーバーでは、.js ファイルにはすでに正しい MIME タイプが設定されていますが、.mjs ファイルにはまだ設定されていません。

Dynamic import

squareBtn.addEventListener('click', () => {
  import('./modules/square.js').then((Module) => {
    let square1 = new Module.Square(myCanvas.ctx, myCanvas.listId, 50, 50, 100, 'blue');
    square1.draw();
    square1.reportArea();
    square1.reportPerimeter();
  })
});

export - JavaScript | MDN

エクスポートされたモジュールは、宣言のあるなしにかかわらず Strict モードで動作します。export 文は、埋め込みスクリプトでは使えません。

2種類のエクスポート方法があります。

  1. 名前付きエクスポート (モジュールごとに 0 以上のエクスポート)
  2. デフォルトエクスポート (モジュールごとに 1 つのエクスポート)
// 個々の機能をエクスポート
export let name1, name2, , nameN; // var, const も
export let name1 = , name2 = , , nameN; // var, const も
export function functionName(){...}
export class ClassName {...}