導入:なぜ今さらCommonJS?
現代のフロントエンド開発ではES Modules(import/export)が主流ですが、Node.js環境や一部のビルドツール、あるいは古いライブラリを扱う際、CommonJS(CJS)の知識は不可欠です。モジュールシステムが混在するプロジェクトで「require is not defined」といったエラーに直面した際、その仕組みを理解しているかどうかで解決スピードが劇的に変わります。今回は、CJSの基本と現場で役立つTipsを解説します。
基礎知識:CommonJSとは何か
CommonJSは、Node.jsで標準採用されているモジュール化の仕組みです。JavaScriptを「一つのファイル=一つのモジュール」として扱い、必要な機能だけを外部に公開(エクスポート)し、必要な場所で読み込む(インポート)ことでコードの再利用性を高めます。
主要なキーワードは以下の2つです。
・module.exports: 外部に公開したい変数や関数を定義する場所。
・require(): 公開されたモジュールを同期的に読み込む関数。
実装:モジュールの定義と読み込み
CJSでは、実行時に動的にモジュールを読み込みます。これはブラウザ環境のES Modulesが非同期的に読み込むのとは異なり、同期的にファイルを読み込むという特徴があります。
具体的には、以下のように実装します。
サンプルプログラム:CJSモジュールの作成と利用
// mathUtils.js(モジュール側)
// 数学的な計算を行う関数を定義します
const add = (a, b) => a + b;
const subtract = (a, b) => a – b;
// module.exportsを使って外部に公開します
// オブジェクトとしてまとめるのが一般的です
module.exports = {
add,
subtract
};
// app.js(呼び出し側)
// requireを使ってモジュールを読み込みます
const mathUtils = require(‘./mathUtils’);
// 公開された関数を呼び出します
console.log(‘足し算の結果:’, mathUtils.add(5, 3));
console.log(‘引き算の結果:’, mathUtils.subtract(10, 4));
応用・注意点:現場で陥りやすいバグの回避策
1. 循環参照の注意: CJSではモジュールAがBを読み込み、BがAを読み込むような「循環参照」が発生すると、読み込み途中の不完全なオブジェクトが返されることがあります。基本的には設計を見直し、依存関係を一方通行にするのが鉄則です。
2. ES Modulesとの混在: 最近のNode.jsでは「.mjs」拡張子(ESM)と「.cjs」拡張子(CJS)で挙動を分けられます。`package.json`の`”type”: “module”`設定の有無によって`require`が使えない場合があるため、プロジェクトの環境設定を必ず確認してください。
3. キャッシュ機能: require()は一度読み込んだモジュールをキャッシュします。同じファイルを複数回読み込んでも、中身は常に同じオブジェクトが返されます。この特性を知っておくと、設定ファイルなどを一度だけ読み込んで使い回す際に便利です。
CJSは古い技術と思われがちですが、Node.jsのエコシステムを支える強力な基盤です。仕組みを正しく理解し、堅牢なアプリケーション開発に役立ててください。