JavaScriptのexport/importについて調べた
JavaScript再入門中。
今週はexport/import
についてメモ。
export/importとは
export 文は、モジュールから関数、オブジェクト、プリミティブな値をエクスポートするための JavaScript モジュールを作成するときに使用します。これらは別のプログラムで、 import 文で使用できます。 エクスポートされたモジュールは宣言のあるなしにかかわらず strict mode で動作します。エクスポート文は、埋め込まれたスクリプトでは使えません。
export - MDNimport 文は、他のモジュールからエクスポートされたバインディング(関数、オブジェクト、プリミティブ)をインポートするために用います。インポートされたモジュールは宣言のあるなしにかかわらずStrict モードで動作します。import 文は、type="module" を指定しない限り、埋め込まれたスクリプトでは使えません。
import - MDN
export
キーワードは、ファイルの外部からアクセス可能であるべき変数や関数にラベル付けをする。
import
キーワードは、export
されたものを読み込む。
エクスポートには、名前付きエクスポート(named exports)
とデフォルトエクスポート(default exports)
の2種類がある。
名前付きエクスポートはモジュールごとに複数持つことができるが、デフォルトエクスポートは1つしか持てない。
// 関数helloをexport export function hello(str) { console.log( `Hello, ${str}!` ); } // セミコロンはつけない(関数式にならないよう注意) // 配列fooのexport export let foo = ['bar', 'baz']; // 定数Hogeのexport export const Hoge = 'hoge'; // クラスUserのexport export class User { constructor(name) { this.name = name; } } // デフォルトエクスポート export default function(){ console.log('default exports!'); }
// 関数helloをimport import { hello } from "./sample.js"; hello('World'); //Hello World! // 配列fooをimport import { foo } from "./sample.js"; console.log(foo); //["bar", "baz"] // 定数Hogeをimport import { Hoge } from "./sample.js"; console.log(Hoge); //hoge // クラスUserをimport import { User } from "./sample.js"; console.log( (new User('tarou')).name ); //tarou // デフォルトエクスポートを変数Sampleにインポート import Sample from "./sample.js"; Sample(); // default exports!
named exports
名前付きエクスポートをimport
で読み込む際は変数名を波括弧で囲む必要があり、別名の設定や、複数同時指定などもできる。
また * as 変数名
で一括インポートできる。
// 別名の設定 import { Hoge as Fuga }from "./sample.js"; console.log( Fuga ); //hoge // 複数同時にimport import { foo, User as Tarou } from "./sample.js"; console.log(foo); //['bar', 'baz'] console.log( (new Tarou('tarou').name) ); //tarou // 一括import。すべての名前付きエクスポートをLibに読み込む import * as Lib from "./sample.js"; // プロパティ名でそれぞれのモジュールにアクセスできる Lib.hello('World'); //Hello, World! console.log( Lib.foo ); //['bar', 'baz']
default exports
デフォルトエクスポート
は、default
キーワードを付与するか、 変数名 as default
で定義する。
また、変数名を必要とせず、無名関数等でもエクスポートできる。
// 無名関数でもエクスポート可(デフォルトエクスポートは1モジュールにつき1つであるため) export default function (){ /*...*/ } //同一モジュールに複数 default が定義されているとエラー export default class{ constructor() { ... } } //SyntaxError: Duplicate export of 'default'
// デフォルトエクスポート let Hoge = "default exports"; // 以下は export default Hoge と等価 export { Hoge as default }; // 名前付きエクスポート let Foo = "named exports"; export { Foo };
import
で読み込む際に波括弧を指定しなかった場合、デフォルトエクスポートが読み込まれる。
また、default
キーワードを使用することで別名をつけたり名前付きエクスポートと同時にimportしたりできる。
// 波括弧をつけないとデフォルトエクスポートがインポートされる import Hoge from "./sample_2.js"; console.log( Hoge ); //default exports // defaultキーワードの別名としてインポート import { default as Fuga }from "./sample_2.js"; console.log( Fuga ); //default exports // 名前付きと同時にimport import { default as Piyo, Foo } from "./sample_2.js"; console.log(Piyo); //default exports console.log( Foo ); //named exports // 一括importした場合、defaultプロパティにデフォルトエクスポートが入っている import * as Lib from "./sample_2.js"; console.log( Lib.default); //default exports console.log( Lib.Foo ); //named exports
import() 関数
import
キーワードにはいくつかの制約がある。
- ブロックの中に置くことはできない
- モジュールパスを変数などで動的に生成することはできない
// ブロックのなかに置くことはできない if(true){ import { hello } from "./sample.js"; // Uncaught SyntaxError: Unexpected token { } // パスにプリミティブな文字列以外を使用することはできない。 let path = "./sample.js"; import { hello } from path; // Uncaught SyntaxError: Unexpected identifier
動的にimportする必要がある場合、import()関数
を使用する。
import()関数はPromise
オブジェクトを返却するただの関数であるため、import
キーワードのような制約を受けずに使用できる。
let path = "./sample.js"; import(path) .then((obj) => { // 各モジュールには、引数objのプロパティからアクセスできる。 obj.hello('World'); obj.default(); });
本文中のコードは以下にまとめてあります。 export/import調査