ES Modules (ESM) と CommonJS (CJS)ってなに？JavaScriptのモジュールシステムの歴史

## 🌐 **モジュールシステムってなに？**
- **モジュールシステム** は、プログラムを**小さな部品（モジュール）に分割**して、**必要な時だけ使える仕組み**だよ。
- 例えば、Reactのコンポーネントや、ユーティリティ関数を別ファイルにして **`import`** / **`require`** するあの仕組み！

---

## 🕰️ **なぜモジュールシステムが必要？**
昔のJavaScript（例えば **jQuery** を使ってた時代）は、すべてのコードが**一つの巨大なファイル**にまとまっていたんだ。

### 🚫 **問題点**
- コードが増えると **管理が大変**。
- 変数名がかぶると **バグが起きやすい**。
- 再利用可能なコード（例えば **関数やクラス**）を、**他のプロジェクトで使いにくい**。

---

## 🌟 **CommonJS (CJS) とは？**
### ⏳ **誕生の背景**
- **2009年** に、**Node.js** の登場とともに生まれたんだ。
- 当時のJavaScriptには、**サーバーサイド（Node.js）** で使える標準的なモジュールシステムがなかったんだよ。
- そこで、**Node.js** が採用したのが **CommonJS** 形式だったの！

### 📦 **CommonJS の特徴**
| 特性 | 説明 |
|------|-------|
| **インポート方法** | `const module = require('module')` |
| **エクスポート方法** | `module.exports = ...` または `exports.foo = ...` |
| **実行方法** | **同期的** にモジュールを読み込む (コードを実行する時にロード) |
| **主な用途** | **Node.js** 環境、特に設定ファイルや古いライブラリ |
| **ブラウザ対応** | ❌ 直接は使えない（ビルドツールが必要） |

##### 📄 **CommonJS のコード例**
```javascript
// mathUtils.js (エクスポート)
function add(a, b) {
  return a + b;
}

module.exports = { add };

// app.js (インポート)
const { add } = require('./mathUtils');
console.log(add(2, 3)); // 5
```

---

## 🚀 **ES Modules (ESM) とは？**
### ⏳ **誕生の背景**
- **2015年 (ES6 / ECMAScript 2015)** で、**JavaScriptの標準仕様**として登場！
- CommonJS は主に **Node.js** で使われていたけど、**ブラウザでも使えるモジュールシステム**が必要だったんだ。
- **ESM (ES Modules)** は、**サーバーサイド (Node.js)** でも **クライアントサイド (ブラウザ)** でも**統一的に使える**んだよ！

### 📦 **ES Modules の特徴**
| 特性 | 説明 |
|------|-------|
| **インポート方法** | `import { module } from 'module'` |
| **エクスポート方法** | `export default ...` または `export const foo = ...` |
| **実行方法** | **非同期的** にモジュールを読み込む (構文解析時にロード) |
| **主な用途** | **モダンなJSフレームワーク (React, Vue, Next.js)** や **ブラウザ** |
| **ブラウザ対応** | ✅ 直接使える (`<script type="module">`) |
| **トップレベル `await`** | ✅ 使える |

##### 📄 **ES Modules のコード例**
```javascript
// mathUtils.mjs (エクスポート)
export function add(a, b) {
  return a + b;
}

// app.mjs (インポート)
import { add } from './mathUtils.mjs';
console.log(add(2, 3)); // 5
```

---

## 🤔 **じゃあ、なんで分かれてるの？**

### 🕰️ **歴史的な経緯**
1. **Node.js (2009年)** が登場 → **CommonJS** を採用
   - Node.js は、サーバーサイドJavaScriptとして、当時唯一の選択肢だった **CommonJS** を取り入れた。
   - しかし、**ブラウザでは使えない** という問題が残っていたんだ。

2. **ECMAScript 2015 (ES6) で ESM が標準化**
   - **ES Modules (ESM)** は、JavaScriptの標準仕様として生まれ、**ブラウザでも使える** というメリットを持っていた。
   - しかし、Node.js の **CommonJS** とは**互換性がない** 部分が多く、2つのモジュールシステムが並立することになったんだ。

3. **モダンなJavaScriptフレームワークの登場**
   - **React, Vue, Svelte, Next.js** など、モダンなフレームワークが **ESM** を採用することで、フロントエンド開発では **ESM** が標準に。
   - 一方、**Node.js** 環境でも、徐々に **ESM** をサポートするようになってきた（例: **"type": "module"** の設定）。

---

## 📦 **今はどう使い分けるのがベスト？**

| シチュエーション | おすすめモジュールシステム |
|-----------------|----------------------------|
| **モダンなWeb開発 (React, Vue, Next.js)** | **ES Modules (ESM)** |
| **Node.js プロジェクト (新規開発)** | **ES Modules (ESM)** |
| **レガシーなNode.js プロジェクト** | **CommonJS (CJS)** |
| **npmパッケージ公開 (互換性重視)** | **CJS + ESM 両方に対応** |
| **設定ファイル (Webpack, ESLint)** | **ESM** が増えている |

---

## 🎯 **まとめ**
- **CommonJS (CJS)** は、主に **Node.js** 用に作られた古いモジュールシステム。`require` / `module.exports` を使う。
- **ES Modules (ESM)** は、**JavaScript標準仕様**として、**Node.js** と **ブラウザ両方** で使える新しいモジュールシステム。`import` / `export` を使う。
- **モダンなプロジェクト** や **ブラウザ対応が必要な場合** は、**ESM** を使うのが推奨されているよ！