エンジニア向け

【TypeScript入門】なぜ export default を使うべきではないのか

export default は、JavaScript や TypeScript でモジュールをエクスポートする際の方法の一つです。特に小規模なプロジェクトでは便利ですが、大規模なプロジェクトではさまざまな問題を引き起こす可能性があります。本記事では、export default のデメリットを詳しく解説し、より良いコーディング方法を提案します。

1. インポート時の名前が統一されない

export default は、インポートする際に好きな名前を付けることができます。そのため、プロジェクト内で異なる開発者が異なる名前を付けてしまい、一貫性が失われることがあります。

例:export default の問題

TypeScript
// utils.ts
export default function formatDate(date: Date) {
    return date.toISOString();
}
TypeScript
// fileA.ts
import formatDate from "./utils";

// fileB.ts
import format from "./utils"; // 別の名前になってしまう

このように、同じ関数をインポートしているのに、ファイルごとに名前が異なってしまいます。これにより、コードの可読性が低下し、管理が難しくなります。

解決策

export default の代わりに、名前付きエクスポート(named export) を使用すると、名前を統一できます。

TypeScript
// utils.ts
export function formatDate(date: Date) {
    return date.toISOString();
}
TypeScript
// fileA.ts, fileB.ts
import { formatDate } from "./utils"; // 名前が統一される

2. 自動補完が効きにくい

エディタ(VS Code など)では、export default を使うと補完が正確に効かないことがあります。名前付きエクスポートを使うと、エディタがどの関数やクラスがエクスポートされているのかを正確に把握し、自動補完をよりスムーズに提供できます。

例:補完が効きにくいケース

TypeScript
// utils.ts
export default function doSomething() {
    console.log("Doing something");
}
TypeScript
// main.ts
import d from "./utils"; // 何の関数かわかりにくい
import doSomething from "./utils"; // どんな関数か推測しにくい

エディタが正確な補完を提供できず、関数の目的が不明確になりがちです。

解決策

名前付きエクスポートを使えば、補完がより明確になります。

TypeScript
// utils.ts
export function doSomething() {
    console.log("Doing something");
}
TypeScript
// main.ts
import { doSomething } from "./utils"; // 自動補完が正確に働く

3. Tree Shaking(最適化)が効きにくい

Tree Shaking とは、未使用のコードを削除してバンドルサイズを削減する最適化技術です。しかし、export default を使うと、Tree Shaking が適切に働かないことがあります。

例:export default の問題

TypeScript
// utils.ts
export default {
    formatDate: (date: Date) => date.toISOString(),
    parseDate: (str: string) => new Date(str),
};
TypeScript
// main.ts
import utils from "./utils";
console.log(utils.formatDate(new Date())); // `parseDate` も一緒にインポートされてしまう

この場合、本来は formatDate だけを使いたいのに、parseDate もバンドルに含まれてしまいます。

解決策

名前付きエクスポートを使うことで、不要な関数をインポートせずに済みます。

TypeScript
// utils.ts
export function formatDate(date: Date) {
    return date.toISOString();
}
export function parseDate(str: string) {
    return new Date(str);
}
TypeScript
// main.ts
import { formatDate } from "./utils"; // `parseDate` はインポートされない

こうすることで、未使用の関数はバンドルに含まれなくなり、ファイルサイズが削減 されます。

4. 複数のエクスポートがあると扱いづらい

export default は 1 ファイルにつき 1 つしか使用できません。そのため、複数の関数をエクスポートしたい場合に不便です。

例:エラーが発生するケース

TypeScript
// math.ts
export default function add(a: number, b: number) {
    return a + b;
}
export function multiply(a: number, b: number) {
    return a * b;
} // エラー!

export default は 1 つしか使えないため、エラーになります。

解決策

すべての関数を名前付きエクスポートにすると、管理が簡単になります。

TypeScript
// math.ts
export function add(a: number, b: number) {
    return a + b;
}
export function multiply(a: number, b: number) {
    return a * b;
}
TypeScript
import { add, multiply } from "./math";

まとめ

問題点export default名前付きエクスポート(推奨)
名前の統一性名前がバラバラになる統一される
エディタ補完効きにくい正確に動作する
Tree Shaking効きにくい無駄なコードを削除しやすい
複数エクスポート1 つしか使えない複数の関数を簡単にエクスポートできる

export default は全く使うべきでない?

小規模なプロジェクトや、1 つのメインクラスや関数だけをエクスポートする場合は export default を使っても問題ありません。しかし、大規模なプロジェクトや長期運用するコードでは名前付きエクスポートを推奨 します。

これで export default のデメリットが理解できたはずです! もし質問があれば、ぜひコメントで教えてください! 😊

-エンジニア向け
-