📄

名前付きexportとデフォルトexportについて

2024/02/02に公開

始めに

インターン生の方にReact等を教えている際によく聞かれるのが
「名前付きエクスポートとデフォルトエクスポートってどっちを使った方が良いんですか?」
という質問。

先日他社でエンジニアをしている友人から同じ事を聞かれたので、意外と需要があるかもしれないなと思い、投稿として残すことにしました。

個人的な解釈のため、間違いがあればコメント等でご指摘いただけますと幸いです。

それぞれの構文

まず始めに構文のおさらいから

デフォルトエクスポート(Default export)

// export 
export default function sampleFunc() {
    return "hoge";
}

import sampleFunc from './path'

名前付きエクスポート(Named export)

export function sampleFunc() {
    return "hoge";
}
import { sampleFunc } from './path'

このように書く事ができます。

違いについて

モジュール名の変更

デフォルトエクスポートの場合、import時にモジュール名を変更する事ができます。

export default function sampleFunc() {
    return "hoge";
}

// ---

import renamedSampleFunc from './path' // <- モジュール名を変更

名前付きエクスポートだとエラーが出てしまうため下記のように書く必要があります。

export function sampleFunc() {
    return message;
}

// ---

import { sampleFunc as renamedSampleFunc } from './path'

複数のexport

名前付きエクスポートの場合、複数のエクスポートが可能です。
デフォルトエクスポートではできません。

export const message = "Hello, world!";

export function sampleFunc() {
    return message;
}

// ---

import { message, sampleFunc } from './path'

筆者の考え

Next.jsのPageファイルなど例外はありますが、私が質問された際には名前付きエクスポートを推奨しています。
理由は主に下記二点です

  1. 複数のモジュールのエクスポートを行うファイルと、そうでないファイルのimportの統一感
  2. 明示的なリネームの記述

importの統一感

基本的にデフォルトエクスポートでプロジェクトを進めていたとして、途中で複数のモジュールをエクスポートしたいという需要が出てきた場合に下記のようになってしまうと少し気持ち悪いです。

import DefaultExportFunc from './path'
import { NamedExportFunc, NamedExportVar } from './path'

明示的なリネーム

デフォルトエクスポートの場合、import文をtypoしてしまった際に気づかずリネームとして扱われ、意図せずそのまま使用してしまう可能性があります。
また、パスが間違っている場合でもそのパスにデフォルトエクスポートされているTypeScriptファイルがあった場合も、リネームしてimportしてしまいかねません。

// sampleの'e'が抜けている
import samplFunc from './path'  <- そのまま通ってしまう
import { samplFunc } from './path' <- エラー

Discussion