名前付きエクスポート
各メンバをエクスポート
変数、関数、クラスの宣言文の先頭にexport
を付けると、その名前のままモジュールのメンバとして外部にエクスポートされる。
export var foo = "foo";
export function bar() {}
export class Baz {
baz() {}
}
次にように、定義済みの変数や関数を後からエクスポートすることもできる。
var foo = "foo";
function bar() {}
class Baz {
baz() {}
}
export {foo, bar, Baz};
メンバごとにインポート
エクスポートされたモジュールをインポートする。import
のあとにインポートしたいメンバの名前を指定し、続いてfrom
のあとにモジュール識別子を指定する。
import {foo, bar, Baz} from "./module";
console.log(foo); // "foo!"
bar();
new Baz();
インポートする変数名を指定
エクスポートされたメンバの名前とは別の変数名としてインポートしたい場合は、import文でas
を使う
import {foo as poo} from "./module";
console.log(poo); // "foo!"
モジュールをまとめてインポート
エクスポートされたメンバを個別ではなく、モジュール全体をまとめてインポートする。参照時はプロパティアクセスのように各メンバを呼び出す。
imoprt * as module from "./module";
console.log(module.foo); // "foo!"
デフォルトエクスポート
名前付きエクスポートで、インポートするためにはエクスポートされたメンバの名前を知っている必要がある。これに対して、モジュール1つに対して1つのメンバに限り名前指定不要でインポートできるのが、デフォルトエクスポート。
名前付きエクスポートに比べて、{}
やas
がないので書き方がシンプル。
// foo.js
export default "foo!";
// bar.js
export default function() {
console.log("bar!")
}
// baz.js
export default class {
constructor() {
console.log("Baz!")
}
}
import a from "./foo";
import b from "./bar";
import c from "./baz";
console.log(a); // "foo!"
b(); // "bar!"
new c(); // "Baz!"
モジュールの定義位置
import文やexport文は、モジュールのトップレベル以外に書くことはできない。if文や関数の中に書くとエラー。
この制約により、ES6モジュールの依存関係はJavaScriptとして実行する前に決定できるため、静的解析が可能。
if (someCondition) {
export default "foo"; //エラー
import bar from "./bar"; //エラー
}
巻き上げ(hoisting)
import文は関数宣言文などと同じように巻き上げ(hoisting)が発生する。どこに書いてもモジュールの冒頭で宣言したことになるため、インポートした変数をimport文より前に使うことができる。
console.log(a); // "foo!"
import a from "./foo";
モジュール内はstrictモード
ES6モジュールは必ずstrictモードとして実行される。また、ES6モジュール内ではトップレベルのthis
がundefined
になる。ブラウザでは通常のスクリプトのトップレベルのthis
はwindwoオブジェクトだが、ES6モジュールは異なる。
モジュール識別子の解決
モジュール識別子(from
の後のモジュール指定パス)は、ローカルファイルは相対パス(拡張子なし)で指定し、npmパッケージはパッケージ名を指定する方式になる。