JavaScript/CommonJS
CommonJS とは
編集CommonJS(CJS)は、JavaScript におけるモジュール規格のひとつで、特にサーバーサイド環境での利用を目的として設計されました。Node.js がその代表的な実装例です。この記事では、CommonJS の仕組み、利点、使用方法、そして他のモジュール規格との比較について詳しく解説します。
CommonJS の目的と背景
編集JavaScript はもともとブラウザ上での動作を主目的とした言語であり、複数のスクリプト間でコードを共有する機能を標準で備えていませんでした。そのため、モジュールシステムが必要になり、CommonJS が誕生しました。以下は CommonJS が解決したいくつかの課題です。
- コードの再利用性向上: モジュールとしてコードを分割することで、再利用性が向上します。
- 依存関係の管理: モジュール間の依存関係を明確に記述できます。
- 名前空間の汚染回避: モジュールごとにスコープが分かれるため、グローバル名前空間の汚染を防ぎます。
CommonJS の基本構文
編集CommonJS モジュールでは、主に以下の 2 つの機能が提供されています:
require
関数: 他のモジュールを読み込むために使用します。module.exports
: モジュールが提供する値や機能を定義します。
モジュールの書き方
編集以下は基本的なモジュールの例です。
- math.js
// 足し算を行う関数 function add(a, b) { return a + b; } // 引き算を行う関数 function subtract(a, b) { return a - b; } // モジュールとしてエクスポート module.exports = { add, subtract };
- app.js
// math.js モジュールを読み込む const math = require('./math'); console.log(math.add(5, 3)); // 8 console.log(math.subtract(5, 3)); // 2
CommonJS の特性
編集同期的なモジュール読み込み
編集CommonJS はモジュールを同期的に読み込みます。そのため、ファイルシステムが同期的にアクセス可能な環境(例: サーバーサイドの Node.js)に適しています。
モジュールのキャッシュ
編集一度読み込まれたモジュールはキャッシュされるため、同じモジュールを複数回 require
しても初回の処理結果が再利用されます。
// 一度読み込まれたモジュールはキャッシュされる const moduleA = require('./moduleA'); const moduleB = require('./moduleA'); // 同じインスタンスを取得 console.log(moduleA === moduleB); // true
グローバルスコープを持たない
編集CommonJS モジュールは独自のスコープ内で実行されます。そのため、グローバル変数を汚染するリスクがありません。
CommonJS の利点
編集- Node.js に標準対応: Node.js 環境でデフォルトのモジュールシステムとして利用可能。
- シンプルな構文:
require
とmodule.exports
だけで動作する簡潔な設計。 - 広範なエコシステム: npm パッケージの多くが CommonJS に基づいています。
CommonJS と他のモジュール規格の比較
編集CommonJS vs ES Modules (ESM)
編集特徴 | CommonJS | ES Modules |
---|---|---|
モジュール読み込み方式 | 同期的 | 非同期的 |
キーワード | require
|
import/export
|
キャッシュ | あり | あり |
実行環境 | Node.js に特化 | ブラウザと Node.js |
ES Modules の例
編集- math.mjs
export function add(a, b) { return a + b; } export function subtract(a, b) { return a - b; }
- app.mjs
import { add, subtract } from './math.mjs'; console.log(add(5, 3)); // 8 console.log(subtract(5, 3)); // 2
CommonJS vs AMD (Asynchronous Module Definition)
編集AMD(Asynchronous Module Definition)は主にブラウザ環境向けに設計され、非同期的なモジュール読み込みをサポートします。一方、CommonJS は同期的な読み込みを前提としています。
AMD の例
編集define(['math'], function(math) { console.log(math.add(5, 3)); // 8 console.log(math.subtract(5, 3)); // 2 });
CommonJS の制約
編集- ブラウザではそのまま動作しない: CommonJS は Node.js を前提としているため、ブラウザで利用するには Webpack や Browserify などのツールが必要です。
- 非同期処理に不向き: 同期的な設計が基本であるため、大量のファイルを扱う場合は効率が低下する可能性があります。
まとめ
編集CommonJS は、特にサーバーサイド JavaScript 環境で広く採用されているモジュールシステムです。そのシンプルさと広範なエコシステムにより、多くの開発者に支持されています。一方で、ES Modules の台頭により、モジュールシステムとしての選択肢が増えており、用途に応じて適切な規格を選ぶことが求められています。