JavaScript/TypeScriptにおけるimport/exportについて、個人的な方針を考えてみました。
デフォルトエクスポートは使わない
値や型をエクスポートするときは、常に名前付きエクスポートを使います。
デフォルトエクスポートを使っている
export default function foo (): void {}
import foo from './foo'
名前付きエクスポートを使っている
export function foo (): void {}
import { foo } from './foo'
なぜなら、名前付きエクスポートにはデフォルトエクスポートに勝るいくつものメリットがあるからです。
詳しくは上記を参照していただくといいかと思いますが、自分が特によいと感じるのは以下の点です。
- インポート時の名前を統一できる
- インポート時にエディタで補完が効く
ただし、Next.jsやNuxt.jsなどのフレームワークがデフォルトエクスポートを要求している場合など、デフォルトエクスポートを使わなければならないケースにおいてはその限りではありません。
1つのファイルにおける役割は1つ
デフォルトエクスポートが1つのファイルに1つしか存在できないのに対し、名前付きエクスポートは複数存在できます。
そうなると役割がまったく異なる複数の値や型をエクスポートすることもできるわけですが、1つのファイルにおける役割は1つに留めます。
1つのファイルに複数の役割が存在する
export function foo (): void {}
export function bar (): void {}
import {
foo,
bar
} from './foobar'
役割ごとにファイルが分割されている
export function foo (): void {}
export function bar (): void {}
import { foo } from './foo'
import { bar } from './bar'
なぜなら、1つのファイルに複数の役割を持たせるとメンテナビリティが低くなるからです。
ただし、1つのファイル内に複数の名前付きエクスポートが存在すること自体は、それらの役割が同じものであればかまいません。
たとえば、エクスポートしたい関数の引数の型もエクスポートする場合などがあてはまります。
export interface Options {
bar: boolean
}
export function foo (options: Options): void {}
import {
foo,
Options
} from './foo'
const options: Options = {
bar: true
}
foo(options)