Open11
named export と default export
- https://betterprogramming.pub/understanding-the-difference-between-named-and-default-exports-in-react-2d253ca9fc22
- https://beta.reactjs.org/learn/importing-and-exporting-components
- https://dev.to/vladimirvovk/default-exports-vs-named-exports-2jm0
- https://blog.uhy.ooo/entry/2021-09-09/answer-named-export/
- https://zenn.dev/yuhr/articles/668dba202726bf
そもそも両者の違い
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 がある」という違いしかないらしい。
両者の特徴
default export
- importする時に名前を変えることができる
- そのファイルが他のexportに比べ何をもっとも提供したいのかがわかる
- React.lazy がそのまま使える
- エディター、IDEによっては入力補完が効きづらい
- 再エクスポートの際に名前をつける必要がある
named export
- エディター、IDEによる入力補完が効く
- ひとつのファイルから複数exportできる
- (名前の変更はできるものの)基本的に決まった名前でimportして使う必要がある
- exportしているファイルが名前を変更すると動作しなくなる
変更に対する強さ
おそらくここが一番よく言われている観点であり、named 派が推している部分でもある。
named export
- export 対象の名前を変更すれば import 側でも変更が必要になり、エラーで変更に気付ける
- export 側で定義した名前をプロジェクト全体で統一して使うように強制される
default export
- export 対象の名前が変わる場合はファイル名も変更すれば import 側で変更を知ることができる
-
eslint-plugin-consistent-default-export-name
を使って、ファイル名と同じ名前でしか export/import できないようにもできる- このプラグインによって、typo に対する弱さを克服できる
コード分割
遅延読み込み
default export 派の主張
- 1 ファイルにはコンポーネントやモジュールが1つであるべきで、複数 export できる named export は使うべきではない
- named export を許容すると本来そのファイルから export すべきではないモジュールを export できてしまう
- モジュールはブラックボックスであり、その内部実装を import する側が知る必要はない
Tree Shaking について
従属物の export について
ちなみに Google の TypeScript Style Guide では named export を使えと言っている
- 1度しか import されないもの (Page コンポーネントなど) は default で、複数箇所で export され得るものは named export
再エクスポートについて
あまり論点にはなっていないが default export を使う場合は少しリスクがある。
それぞれの書き方の違いは以下の通り。
default export
export { default as generatePassword } from './generatePassword'
named export
export * from './generatePassword'
default export したモジュールを再エクスポートする際に名前をつける必要があるが、ここで typo すると定義している名前と再エクスポートしている名前が違っていても気付けない。