Open11

named export と default export

Kento SasakiKento Sasaki

そもそも両者の違い

default export
const foo = () => {
  console.log('Hello World!')
}

export default foo

// ---------------- ↓ import 側 ----------------

import foo from './foo'

foo()
named export
export const bar = () => {
  console.log('bar')
}

// ---------------- ↓ import 側 ----------------

import { bar } from './bar'

bar()

ちなみに実装的には default export は、「default という名前で export でき、default という名前で import する際の syntax sugar がある」という違いしかないらしい。

Kento SasakiKento Sasaki

両者の特徴

default export

  • importする時に名前を変えることができる
  • そのファイルが他のexportに比べ何をもっとも提供したいのかがわかる
  • React.lazy がそのまま使える
  • エディター、IDEによっては入力補完が効きづらい
  • 再エクスポートの際に名前をつける必要がある

named export

  • エディター、IDEによる入力補完が効く
  • ひとつのファイルから複数exportできる
  • (名前の変更はできるものの)基本的に決まった名前でimportして使う必要がある
  • exportしているファイルが名前を変更すると動作しなくなる
Kento SasakiKento Sasaki

変更に対する強さ

おそらくここが一番よく言われている観点であり、named 派が推している部分でもある。

named export

  • export 対象の名前を変更すれば import 側でも変更が必要になり、エラーで変更に気付ける
  • export 側で定義した名前をプロジェクト全体で統一して使うように強制される

default export

  • export 対象の名前が変わる場合はファイル名も変更すれば import 側で変更を知ることができる
  • eslint-plugin-consistent-default-export-name を使って、ファイル名と同じ名前でしか export/import できないようにもできる
    • このプラグインによって、typo に対する弱さを克服できる
Kento SasakiKento Sasaki

エディター、IDE の入力補完について

おそらく変更に対する強さの観点に次いでよく言われる観点で、named 派が推している部分。
ただ、default export でもわりと補完してくれるので大きな差はなさそう。

使いたい関数を入力していると import 先をサジェストしてくれる
Image from Gyazo

import 文を書いている途中でパスをサジェストしてくれる
Image from Gyazo

Kento SasakiKento Sasaki

default export 派の主張

  • 1 ファイルにはコンポーネントやモジュールが1つであるべきで、複数 export できる named export は使うべきではない
    • named export を許容すると本来そのファイルから export すべきではないモジュールを export できてしまう
  • モジュールはブラックボックスであり、その内部実装を import する側が知る必要はない
Kento SasakiKento Sasaki

再エクスポートについて

あまり論点にはなっていないが default export を使う場合は少しリスクがある。
それぞれの書き方の違いは以下の通り。

default export
export { default as generatePassword } from './generatePassword'
named export
export * from './generatePassword'

default export したモジュールを再エクスポートする際に名前をつける必要があるが、ここで typo すると定義している名前と再エクスポートしている名前が違っていても気付けない。