Reactのnamed exportのメリット(default exportとの比較)

## アジェンダ
Reactで開発する際に、エクスポートする方法には大きく分けて`default export`と`named export`があります。
私は以前から、`default export`を多くの機会で使用しておりました。
ただ、他の有識者にお話をお聞きしているうちに`named export`には、かなりのメリットがあるのではと考え始めました。
それぞれに利点があると思いますが、ここでは特に`named export`を使うメリットに焦点を当ててまとめてみたいと思います。

## named exportとは

まず、大前提として`named export`とは何かを簡単に記述します。
`named export`は、特定の名前を付けてエクスポートする方法です。
複数の関数やコンポーネントを1つのファイルからエクスポートすることが可能です。

以下のコード例では、`MyComponent`と`anotherFunction`という2つの名前付きエクスポートを行っています。

```tsx
import { FunctionComponent } from "react";

// named export
export const MyComponent: FunctionComponent = () => {
  return <div>Hello, World!</div>;
};

export const anotherFunction = (): void => {
  console.log("This is another function");
};
```

この例では、`MyComponent`と`anotherFunction`がそれぞれ名前付きエクスポートとして定義されています。インポートする際には、以下のように特定の名前を指定してインポートする必要があります。

```tsx
import { MyComponent, anotherFunction } from './myModule';
```

```tsx
import MyComponent from './myModule1'; // MyComponentがエクスポートされたモジュール
import anotherFunction from './myModule2'; // anotherFunctionがエクスポートされたモジュール
```

これを、`default export`だと、1つのモジュールに1つの`default export`しか使うことができないので、使用することができません。

## named exportのメリット(default exportとの比較)

### 1.複数のエクスポート

`named export`は複数の関数やコンポーネントを1つのファイルからエクスポートするのに適しています。例えば、以下のように1つのファイルに複数のエクスポートを定義することができます。

```tsx
import { FunctionComponent } from "react";

// myModule.tsx
export const ComponentA: FunctionComponent = () => <div>Component A</div>;
export const ComponentB: FunctionComponent = () => <div>Component B</div>;
export const utilityFunction = (): void => {
  // some utility code
};
```

このファイルからは、複数のコンポーネントや関数をインポートすることができます。

```tsx
import { ComponentA, ComponentB, utilityFunction } from './myModule';
```

一方、`default export`は1つのファイルから1つのデフォルトエクスポートしかできません。

```tsx:❌
import { FunctionComponent } from "react";

// default export ❌
const ComponentA: FunctionComponent = () => <div>Component A</div>;
export default ComponentA;

// default export ❌
const ComponentB: FunctionComponent = () => <div>Component B</div>;
export default ComponentB;

// default export ❌
const utilityFunction = (): void => {
  // some utility code
};
export default utilityFunction;
```

この場合、それぞれの関数やコンポーネントを個別のファイルに分ける必要があります。

```tsx
import ComponentA from './ComponentA';
import ComponentB from './ComponentB';
import utilityFunction from './utilityFunction';
```

### 2.インポート時の明示性

`named export`を使用すると、インポートする際にどのコンポーネントや関数を使用しているかが明示的になります。

```tsx
import { ComponentA, ComponentB } from './myModule';
```

一方、`default export`ではインポートする名前を任意に決めることができため、そのまま持ってきた名前なのか別名(エイリアス)なのか区別がつきずらいのではと考えます。

```tsx
import MyComponent from './myModule';
```

もし、`named export`で名前を任意に変更したい場合は、別名（エイリアス）を付けてインポートすることができ、こちらの方が視覚的に、元々の名前なのか、任意で付けた名前なのかを区別もしやすいのではと思います。

```tsx
import { ComponentA as FirstComponentA } from './firstModule';
import { ComponentA as SecondComponentA } from './secondModule';
```

### 3.オートコンプリートのサポート

`named export`は、多くのコードエディタやIDEでオートコンプリート機能をサポートしています。そのため、エクスポートされた名前を簡単に補完でき、開発効率が向上が見込めます。

### 4.再エクスポートが容易
あるファイルでエクスポートされたものを別のファイルから再度エクスポートすることが簡単にできることを指します。再エクスポートを利用すると、複数のファイルからエクスポートされたモジュールを一箇所に集約して管理できるようになります。
これは、大規模なアプリケーションでモジュールを整理する際に特に有用なのではと考えております。

```tsx
import { FunctionComponent } from "react"

// file1.tsx
export const ComponentA: FunctionComponent = () => <div>Component A</div>;
export const ComponentB: FunctionComponent = () => <div>Component B</div>;

// index.tsx
export { ComponentA, ComponentB } from './file1';
```

このように、再エクスポートを行い、インポートする側は単一のエントリーポイントから必要なコンポーネントをインポートできます。

## まとめ
`named export`は、複数のエクスポートを一つのファイルにまとめることができ、インポート時の明示性やオートコンプリートのサポート、再エクスポートの容易さなど様々なメリットがあるのではと感じました。
ただ、若干`named export`のメリットの側面でリサーチしているので、default exportの良さを把握仕切れてないかもしれません。
引き続き、この議題については、リサーチしていこうと思います。


## 参考

- [Avoid using default exports - DEV Community](https://dev.to/phuocng/avoid-using-default-exports-a1c)