JavaScriptのdefault exportは、「default」という名前でnamed exportをしているということになります。
いや ES Modulesにおいてdefault exportは「defaultという名前でnamed exportする」こととして定義されている(ぇ
— 🈚️うひょ🤪✒📘 (@uhyo_) April 16, 2020
この投稿では、具体的なコードを示しながら、default exportにちゃんと「default」という名前がついているのを確認していきたいと思います。
named export と default export
まず、おさらいとして、named exportとdefault exportの書き方を見比べてみます。
// named export
export const foo = 1
// default export
export default 1
named exportのほうは、変数名がついていますが、default exportのほうは、値です。
これらをインポートするコードは次の例のようになります。named exportの値はmodule.js
で決められた名前でインポートします。それに対し、default exportの値は使う側のmain.js
が変数名を決めます。下の例ではbar
と名づけています。
// named export
import { foo } from "./module.js"
// default export
import bar from "./module.js"
よくある誤解
上のコードだけで2種類のexportを比べてみると、その違いは次のようなものだと思うのではないでしょうか?
- named export: 名前がついているエクスポート
- default export: 名前がついていないエクスポート
これはよくある誤解のようです。誤解とまではいかずとも、もう少し的確なメンタルモデルがあります。
MDN web docsでは、2つの違いを次のように説明しています:
エクスポート方法は、名前付きとデフォルトの 2 種類あります。名前付きエクスポートはモジュールごとに複数持てますが、デフォルトエクスポートは 1 つに限ります。
「exportを何個持てるか」についてだけ言っていて、「名前がついているか」については言っていないのです。
defaultという「名前」がつく
なぜ、名前の有無が語られないかというと、default exportでエクスポートされた値には「default」という名前が与えられるためと考えられます。
例えば、次のdefault exportは、
export default 1
いわば、次のようなnamed exportと同じような意味合いなのです。
export const default = 1
ただ、default
が予約語なので、default
という変数を定義することはできません。なので、当然const default
なんてものををnamed exportもすることはできません。
defaultという名前がつくのを確認する方法
「それは内部的な話なんでしょう? defaultという変数にプログラマが触れられないなら、別に気にすることでもないんじゃ?」
そう思われそうですが、JavaScriptのコード上でもいくつか「default」という変数を参照できる例があります。場合によってはdefault
という変数を参照する必要が出てくるコードもあります。
例えば、import * as name
構文を使ったコードです:
// helloWorld.js
export default function () {
console.log('Hello World')
}
// main.js
import * as module from './helloWorld.js'
module.default()
//出力結果: Hello World
helloWorld.js
でexport default
された関数が、main.js
ではdefault
という変数に入っていることが確認できます。
2つの目の例は、dynamic importです:
// helloWorld.js
export default function () {
console.log('Hello World')
}
// main.js
import('./helloWorld.js')
.then(module => module.default())
//出力結果: Hello World
これも同様にmain.js
では、関数がdefault
という名前の変数に入ってきます。dynamic importでは、このdefault
という変数にアクセスしないと、default exportされたものを利用することができません。
3つめの例は、export { variable as name }
構文(エクスポート時の名前変更構文)を使った場合も、default
という名前の出現が確認できます:
// helloWorld.js
const func = function () {
console.log('Hello World')
}
export {
func as default, // ここ
func as helloWorld
}
// main.js
import func from './helloWorld.js'
import { helloWorld } from './helloWorld.js'
func() //=> Hello World
helloWorld() //=> Hello World
以上が、プログラマが実際にJavaScriptのコード上で「default」という名前を確認できる例でした。
まとめ
default exportされた値には、「default」という名前が与えられる。
所感
一見特別そうなdefault exportですが、勝手に「default」という名前を付けてくれるnamed exportだと思うと、なんとなく整理されたような気がしてきます。
最後までお読みくださりありがとうございました。Twitterでは、Qiitaに書かない技術ネタなどもツイートしているので、よかったらフォローお願いします→Twitter@suin