この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:4
ページ更新者:guest
更新日時:2026-06-11 07:10:02

タイトル: 他ファイルの関数読み込み
SEOタイトル: JavaScript モジュール完全ガイド(ES Modules import / export / CommonJS / 名前付き / デフォルト)

この記事の要点
  • JavaScript で他ファイルの関数を読み込むには ES Modules (ESM) または CommonJS を使う
  • ES Modules: export / import 構文。ブラウザ / Node.js の標準
  • CommonJS: module.exports / require()Node.js 旧来の方式、まだ広く現役
  • 名前付き export は複数定義可、default export は 1 ファイル 1 つ
  • 読み込み形式の指定: 拡張子 .mjs / package.json の "type": "module" で ESM、それ以外は CJS (Node)

JavaScript のモジュールシステム

JavaScript で「他のファイルに書いた関数」を呼び出すにはモジュール機構を使います。現在は次の 2 方式が混在しています。

方式構文主な環境
ES Modules (ESM)import / exportブラウザ・モダン Node.js (推奨)
CommonJS (CJS)require() / module.exports従来の Node.js

新規プロジェクトは ESM が標準。既存の Node.js コードでは CJS が現役です。

ES Modules — export

名前付き export

// math.js
export function add(a, b) {
    return a + b;
}

export function sub(a, b) {
    return a - b;
}

export const PI = 3.14159;

default export

// greet.js
export default function greet(name) {
    return `Hello, ${name}!`;
}

1 ファイルに 1 つだけ。「このモジュールが提供するメイン機能」を表します。

ES Modules — import

// main.js

// 名前付き import
import { add, sub, PI } from './math.js';

console.log(add(2, 3));   // 5
console.log(PI);          // 3.14159

// default import (任意の名前を付けられる)
import greet from './greet.js';
console.log(greet('Alice'));

// まとめて import
import * as math from './math.js';
console.log(math.add(1, 2));

// エイリアス
import { add as plus } from './math.js';
console.log(plus(2, 3));

// 副作用だけ実行 (return 値を使わない)
import './setup.js';

CommonJS — module.exports / require

Node.js が伝統的に使ってきた方式。ファイル拡張子 .js でかつ package.json に "type": "module" がない場合の Node.js ではこちらが標準です。

// math.js (CommonJS)
function add(a, b) { return a + b; }
function sub(a, b) { return a - b; }

module.exports = { add, sub, PI: 3.14159 };

// または
exports.add = add;
exports.sub = sub;
// main.js (CommonJS)
const { add, sub, PI } = require('./math.js');

console.log(add(2, 3));   // 5

// オブジェクトをまるごと
const math = require('./math.js');
console.log(math.add(1, 2));

ESM と CJS の使い分け

観点ESMCJS
構文import / exportrequire / module.exports
非同期/同期非同期(ロード時に静的解析)同期
循環参照サポート (一部制約あり)サポート (壊れやすい)
Tree Shaking○ (未使用 export を削除)×
ブラウザ○ (ネイティブ対応)× (バンドラ必須)
__dirname / __filename使えない (import.meta.url 経由)使える

Node.js での ESM 有効化

// package.json
{
  "name": "myapp",
  "type": "module",
  "main": "index.js"
}

"type": "module" を入れると、その配下の .js が ESM として扱われます。CJS を一部混ぜたい場合はそのファイルだけ .cjs 拡張子にします。逆に CJS プロジェクト内で 1 つだけ ESM にしたい場合は .mjs

ブラウザでの ESM

<!-- type="module" を付けるだけで ESM になる -->
<script type="module" src="./main.js"></script>

<!-- インラインでも OK -->
<script type="module">
    import { add } from './math.js';
    console.log(add(1, 2));
</script>

ブラウザの ESM ではパスは相対 / 絶対 URL のみ'./math.js''/lib/math.js' は OK、'math.js''lodash' (bare specifier)は基本不可(importmap 使用時除く)。

動的 import

遅延読み込みや条件分岐で読み込む場合は import() 関数形式を使います(Promise を返す)。

// クリック時に初めて読み込む
button.addEventListener('click', async () => {
    const { showModal } = await import('./modal.js');
    showModal();
});

// 条件付き
if (user.isAdmin) {
    const admin = await import('./adminPanel.js');
    admin.render();
}

動的 import はバンドラ (Webpack / Vite / Rollup) でもコード分割のトリガーとして使われます。

FAQ

Q: importrequire 混ぜていい?
A: Node.js では制約あり。ESM から CJS は import x from 'cjsmodule' でほぼ動く。CJS から ESM は動的 import() が必要。

Q: __dirname が ESM で使えない
A: import.meta.url を使う。const __dirname = path.dirname(fileURLToPath(import.meta.url));

Q: ファイル拡張子は省略できる?
A: Node.js の ESM は拡張子必須./math.js)。CJS / バンドラでは省略可。

Q: TypeScript ではどっち?
A: ソース上は import/export で書き、tsconfig.jsonmodule オプションで出力先を選ぶ(ESNext / CommonJS / NodeNext など)。