Node.js モジュールインポート
Node.js プロジェクトを書き始めるとき、最初に直面する問題の一つは——モジュール(module)をインポートする方法です。
Node.js では、モジュールとは再利用可能な JavaScript ファイルのことです。モジュール同士はインポート(import)とエクスポート(export)によって相互に通信します。
Node.js エコシステムは主に 2 つのモジュールシステムをサポートしています:CommonJSと ES Modules (ESM)。
| モジュールシステム | 仕様 | ファイル拡張子 | インポート方法 | エクスポート方法 |
|---|---|---|---|---|
| CommonJS | Node.js が初期に使用 | .js |
require() |
module.exports / exports |
| ES Module (ESM) | ECMAScript 標準 | .mjs 或 "type": "module" |
import |
export / export default |
CommonJS モジュールシステム
CommonJS は Node.js で最も初期に、そして最も広く使われているモジュールシステムです。同期ロード方式を採用しており、モジュールのロード中はプログラムの実行がブロックされ、ロードが完了するまで待機します。
インポートとエクスポート
CommonJS では、あなたはrequire()関数を使ってモジュールをインポートし、module.exports 或 exportsオブジェクトを使ってモジュールをエクスポートします。
エクスポート方法:
math.js ファイルコード:
function add(a, b) {
return a + b;
}
module.exports = { add };
// または:exports.add = add;
インポート方法:
例
const math = require('./math.js');
console.log(math.add(2, 3)); // 5
モジュールが外部から自分の内容にアクセスできるようにするには、module.exports または exports を使ってエクスポートする必要があります:
例
const name = 'Alice';
const age = 30;
// 方法1:module.exports を使って単一のオブジェクトまたは値をエクスポート
module.exports = {
name: name,
age: age,
sayHello: () => {
console.log(`Hello, my name is ${name}.`);
}
};
// 方法2:exports を使って複数の名前付き変数をエクスポート
// exports は module.exports の参照です
exports.name = name;
exports.age = age;
exports.sayHello = () => {
console.log(`Hello, my name is ${name}.`);
};
インポート方法:
例
const user = require('./user.js');
console.log(user.name); // 出力: Alice
user.sayHello(); // 出力: Hello, my name is Alice.
// 分割代入(デストラクチャリング)も直接できます
const { name, age } = require('./user.js');
console.log(name); // 出力: Alice
CommonJS の特徴:
- 同期ロード:サーバーサイド環境に適しています。モジュールは通常ローカルファイルシステムにあるため、ロードが高速です。
- 実行時ロード:
require()コードの任意の場所で呼び出せるため、条件に応じてモジュールを動的にロードできます。 - キャッシュ機構:
require()ロードされたモジュールはキャッシュされ、2回目のインポート時にはキャッシュから直接読み取られるため、重複ロードが回避されます。
ES Module(ESM)仕様
ESM は JavaScript 公式のモジュール標準であり、非同期ロードを採用し、ブラウザと現代の Node.js アプリケーションで推奨されています。
ESM では、あなたはimportステートメントを使ってモジュールをインポートし、exportステートメントを使ってモジュールをエクスポートします。
ESM を有効にする:Node.js で ESM を使用するには、package.json ファイルに次を追加する必要があります"type": "module"、またはファイル拡張子を.mjs。
// package.json
{
"type": "module"
}
モジュールをエクスポート:
例
export function add(a, b) {
return a + b;
}
export default function multiply(a, b) {
return a * b;
}
モジュールをインポート:
例
import multiply, { add } from './math.mjs';
console.log(add(2, 3)); // 5
console.log(multiply(2, 3)); // 6
有効にする方法:
ファイル拡張子は.mjs
または package.json に次を追加:
{ "type": "module" }
ESM は 2 つのエクスポート方法をサポートしています:名前付きエクスポート(Named Exports)とデフォルトエクスポート(Default Export)です。
例
// 名前付きエクスポート
export const name = 'Bob';
export const age = 25;
// デフォルトエクスポート
const sayHello = () => {
console.log(`Hello, my name is ${name}.`);
};
export default sayHello;
インポート方法:
例
// 名前付きエクスポートをインポート
import { name, age } from './user.mjs';
console.log(name); // 出力: Bob
// デフォルトエクスポートをインポート
import sayHello from './user.mjs';
sayHello(); // 出力: Hello, my name is Bob.
// 名前付きとデフォルトの両方を同時にインポート
import sayHello, { name } from './user.mjs';
console.log(name);
sayHello();
// すべての名前付きエクスポートをインポートし、オブジェクトのプロパティとして扱う
import * as user from './user.mjs';
console.log(user.name);
user.default(); // デフォルトエクスポートは default プロパティになります
ESM の特徴:
- 非同期ロード:デフォルトでは非同期ロードであり、メインスレッドをブロックしないため、ブラウザ環境により適しています。ただし、Node.js では通常は同期ロードとして動作します。
- 静的解析:
importとexportステートメントはコードの実行前にモジュールの依存関係を決定できるため、ツール(Webpack、Vite など)はより良い最適化(例えばTree Shaking)。 - 厳格モード:ESM モジュールはデフォルトで厳格モードで実行されます。
CommonJS と ESM の違い
| 項目 | CommonJS | ESM |
|---|---|---|
| 構文 | require / module.exports |
import / export |
| ロードメカニズム | 実行時同期ロード | コンパイル時静的ロード |
| デフォルトサポート | Node.js がデフォルトでサポート | 需 .mjs 或 "type": "module" |
| 適したシナリオ | バックエンドスクリプト、レガシープロジェクト | モダンなフロントエンド・バックエンドプロジェクト、Tree-shaking |
| 混在利用の可否 | 直接混在できない(追加設定が必要) | 直接混在できない(追加設定が必要) |
混在利用
Node.js は比較的新しいバージョンで 2 つのモジュールシステムの共存をサポートしています。同じプロジェクト内で CommonJS と ESM を同時に使用できますが、以下の点に注意する必要があります:
- ESM では直接使用できない
require()とmodule.exports。 - CommonJS では直接使用できない
importとexport。 -
ESM で CommonJS モジュールをインポートしたい場合は、直接
importステートメントを使用でき、ESM はそれをデフォルトエクスポートとして扱います。// commonjs_module.js module.exports = { data: 'hello' }; // esm_module.mjs import commonModule from './commonjs_module.js'; console.log(commonModule.data); // 输出: hello -
CommonJS で ESM モジュールをインポートしたい場合は、動的
import()関数。// esm_module.mjs export const name = 'Bob'; // commonjs_module.js async function loadESM() { const { name } = await import('./esm_module.mjs'); console.log(name); } loadESM();
ベストプラクティスの推奨
新しいプロジェクトについては、ES Modules(ESM)の使用を強くお勧めします。これは JavaScript の公式標準であるだけでなく、現代のフロントエンドツールチェーン(Vite、Next.js など)との互換性も高く、Tree Shaking などの最適化技術を最大限に活用して、バンドル後のコードサイズを削減できます。
古い CommonJS プロジェクトを保守していて、ESM の機能が必要ない場合は、CommonJS を引き続き使用できます。ただし、新しい依存関係を導入する必要がある場合や ESM の新機能を活用したい場合は、段階的に移行するか、混在モードで移行を進めることを検討できます。
その他の拡張機能