概要
小さな関数を分割する。
それぞれの責任を明確に保つ。
複数人で開発しても破綻しないコードを築く。
それを支えるのが、モジュールという設計単位である。
JavaScriptの import
/ export
構文は、単なる構文の話ではない。責任の明文化と依存の制御という、設計思想そのものである。
本記事では、モジュールの基本構文から、ユースケースに応じた分割設計・責務管理・依存構造の制御まで、構造的に解説する。
対象環境
モダンJavaScript(ES Modules)対応環境(ES6〜)
Node.js(ESMフラグあり) / Vite / Webpack / Babel など
import / export の基本構文
✅ 名前付きエクスポート(Named Export)
// utils.js
export function add(a, b) {
return a + b;
}
export const VERSION = '1.0.0';
// main.js
import { add, VERSION } from './utils.js';
✅ デフォルトエクスポート(Default Export)
// logger.js
export default function log(msg) {
console.log(`[LOG] ${msg}`);
}
// main.js
import log from './logger.js';
✅ まとめてインポート
import * as utils from './utils.js';
utils.add(1, 2);
「どう分けるか」より「なぜ分けるか」
モジュール設計の目的:
- 責務を切る(関心の分離)
- 再利用可能にする
- 変更の影響範囲を限定する
- テストしやすくする
- 依存関係を明示する
実務におけるモジュール分割例
✅ ユーティリティ(副作用なし)
/src
/utils
- string.js
- math.js
// string.js
export const capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);
✅ ビジネスロジック層(ドメインを意識)
/src
/services
- userService.js
/repositories
- userRepository.js
→ 役割の意味単位で分ける
✅ UI層との接続(フレームワーク対応)
/components
- UserCard.vue
/hooks
- useUser.js
/store
- userStore.js
モジュール設計の原則(SOLIDより派生)
原則 | 説明 |
---|---|
単一責任の原則 | 1ファイル1責任 |
明示的依存の原則 | importにすべての依存を書く |
再利用性の高い構造 | 依存の方向は上から下へ(UI → ロジック) |
export の使い分け戦略
状況 | export方式 | 理由 |
---|---|---|
ユーティリティ関数集 | Named export | 複数の関数を個別に使える |
コンポーネント単体 | Default export | import側で名前自由 |
フレームワークと連携 | Default + Named 混在 | 柔軟性が必要な場合あり |
index.js 経由の再エクスポート | Named export | モジュールをまとめて公開できる |
index.js によるエントリポイント最適化
// /utils/index.js
export * from './string.js';
export * from './math.js';
import { capitalize } from './utils'; // ← ルート経由でアクセス
→ import文の見通しが良くなり、リファクタリングにも強くなる
よくあるアンチパターン
❌ 1ファイルに複数の責務を詰め込む
// user.js に UI, fetch, ロジック全部書いてしまう
→ ✅ 役割ごとに明確に分ける:UserCard.vue
, userService.js
, userSchema.js
等
❌ デフォルトexportで全部返す
// utils.js
export default {
add, subtract, divide
};
→ ✅ 名前付き export にして静的解析・Tree Shaking に強くする
結語
モジュールとは「処理のまとまり」ではなく、「責務のまとまり」である。
そして import / export
はその責務を他にどう明示するか、どう制限するかのインターフェースである。
設計とは、コードをどう“切るか”ではなく、どう“持たせないか”だ。
分けることで自由になり、自由の上に構造が生まれる。
JavaScriptモジュールは、書き方ではなく、語り口そのものである。