【JavaScript】インポート/エクスポートルールの整理
こんにちは!
スマレジ テックファームのMichiです!
JavaScriptのインポートとエクスポートのルールってたくさんあってややこしいですよね...。
というわけで、今回の記事で整理していきたいと思います。
基本形
個別にエクスポートする
変数、関数、クラスのぞれぞれは、宣言前にexport
をつけることで、個別にエクスポートすることができます。
input.js
// 変数のエクスポート export const name = "Michi"; // 関数のエクスポート export function hello() { console.log("Hello"); } // クラスのエクスポート export class Member { constructor(lastName, firstName) { this.lastName = lastName; this.firstName = firstName; } getName() { return this.lastName + " " + this.firstName; } }
まとめてエクスポートする
ブラケット{}
を使用することで、まとめてエクスポートすることができます。
input.js
const name = 'Michi' function hello() { console.log('Hello') } class Member { constructor(lastName, firstName) { this.lastName = lastName this.firstName = firstName } getName() { return this.lastName + ' ' + this.firstName } } // まとめてエクスポート export { name, hello, Member }
インポートする
エクスポートしたそれぞれの変数、関数、クラスは、import
宣言をすることによって、別モジュールで使用できます。
インポートするものは、ブラケット{}
の中に羅列します。
output.js
// input.jsからインポート import { name, hello, Member } from './input.js' console.log(name) // 結果:Michi hello() // 結果:Hello const member1 = new Member('山田', '太郎') console.log(member1.getName()) // 結果:山田 太郎
一括でインポートする
インポートするものの量が多い場合は、import * as <obj>
という構文で、オブジェクトとして一括インポートできます。
それらを使用したいときは、<obj>.<呼び出したい変数・関数・クラス>
という形で呼び出します。
output.js
// オブジェクトとして一括インポート import * as input from './input.js' console.log(input.name) // 結果:Michi input.hello() // 結果:Hello const member1 = new input.Member('山田', '太郎') console.log(member1.getName()) // 結果:山田 太郎
ただし、この形はあまり推奨しません。 理由は、
- 呼び出し時のコードが長くなるから:
console.log(name)
→console.log(input.name)
- インポートしたものが、いつどこで使われているのか分かりにくいから
import { name, hello, Member } from './input.js'
のように、明示的にインポートする方がおススメです。
別名を使う
as
を利用することで、別名でエクスポート/インポートできます。
別名エクスポート
input.js
class Member { constructor(lastName, firstName) { this.lastName = lastName this.firstName = firstName } getName() { return this.lastName + ' ' + this.firstName } } // 別名でエクスポート export { Member as Person }
output.js
import { Person } from './input.js' const member1 = new Person('山田', '太郎') console.log(member1.getName()) // 結果:山田 太郎
別名インポート
input.js
export class Member { constructor(lastName, firstName) { this.lastName = lastName this.firstName = firstName } getName() { return this.lastName + ' ' + this.firstName } }
output.js
import { Member as Person } from './input.js' const member1 = new Person('山田', '太郎') console.log(member1.getName()) // 結果:山田 太郎
デフォルトエクスポート
デフォルトエクスポートとは
モジュールの中にエクスポートするものが1つしかない場合は、デフォルトエクスポートを使用することができます。
使い方はexport
宣言の後に、default
を付けるだけです。
member.js
// デフォルトエクスポート export default class { constructor(lastName, firstName) { this.lastName = lastName this.firstName = firstName } getName() { return this.lastName + ' ' + this.firstName } }
この場合、エクスポートする関数/クラスに名前を付ける必要はありません。
なぜなら、エクスポートされるものは1つしかないので、名前で識別する必要ながないためです。
デフォルトエクスポートをインポートする場合は、インポート側で変数(仮の名前)を付けてあげる必要があります。
またこの場合、ブラケット{}
は不要です。
output.js
// Memberという変数を付ける import Member from './member.js' const member1 = new Member('山田', '太郎') console.log(member1.getName()) // 結果:山田 太郎
デフォルトエクスポート時のファイル名
ところで先ほど、input側のファイルを以前までの例と違い、member.js
という名前に変えていたのにお気づきでしょうか?
これはコードの一貫性を保つために、インポートされた変数はファイル名に対応するべきという規則があるからです。例えば、input.js
というファイルからデフォルトエクスポートされた場合、インポート側(output.js
)からはどんな名前でもインポートできます。
output.js
// どんな名前でもインポートできる import input from './input.js' import Member from './input.js' import hoge from './input.js'
しかし、インポートの変数名とファイル名が乖離していると、余計な混乱が生じます。ですので、この場合はエクスポートされたモジュールの内容を表すmember
という名前で、変数名とファイル名を統一するべきです。
まとめ
JavaScriptのインポート/エクスポートルールについて解説しました。
JavaScriptは明示的にexport
を書かないといけないのがやっかいですよね。Pythonみたいにimport
だけで済めばいいんだけどなあ。