require と module.exports

CommonJS では、require() でモジュールを読み込み、module.exports で値をエクスポートします。Node.js で長年使われてきた標準的な書き方です。

require() の基本

require() はモジュールを同期的に読み込み、エクスポートされた値を返します。

// 相対パスでの読み込み
const utils = require('./utils');
const helper = require('../lib/helper');

// node_modules からの読み込み
const express = require('express');
const lodash = require('lodash');

// Node.js 組み込みモジュール
const fs = require('fs');
const path = require('path');

module.exports の基本

エクスポートしたい値を module.exports に代入します。

// 関数をエクスポート
module.exports = function greet(name) {
  return `Hello, ${name}!`;
};
// main.js
const greet = require('./greet');
console.log(greet('World')); // "Hello, World!"

複数の値をエクスポート

オブジェクトとして複数の値をまとめてエクスポートします。

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

function multiply(a, b) {
  return a * b;
}

const PI = 3.14159;

module.exports = {
  add,
  multiply,
  PI
};
// main.js
const math = require('./math');
console.log(math.add(2, 3));  // 5
console.log(math.PI);         // 3.14159

// 分割代入も可能
const { add, PI } = require('./math');

exports ショートカット

exportsmodule.exports への参照なので、プロパティを追加する形で使用できます。

// utils.js
exports.formatDate = function(date) {
  return date.toLocaleDateString();
};

exports.formatNumber = function(num) {
  return num.toLocaleString();
};

exports.VERSION = '1.0.0';

ただし、exports に直接オブジェクトを代入しても動作しません。

// これは動作しない!
exports = {
  name: 'test'
};

// こちらを使う
module.exports = {
  name: 'test'
};

クラスのエクスポート

// User.js
class User {
  constructor(name) {
    this.name = name;
  }
  
  greet() {
    return `Hello, ${this.name}!`;
  }
}

module.exports = User;
// main.js
const User = require('./User');
const user = new User('Alice');
console.log(user.greet()); // "Hello, Alice!"

条件付き require

CommonJS では、条件分岐の中で require を使用できます。

let db;

if (process.env.NODE_ENV === 'production') {
  db = require('./db-production');
} else {
  db = require('./db-development');
}

キャッシュの動作

require() で読み込んだモジュールはキャッシュされ、2回目以降は同じオブジェクトが返されます。

const a = require('./module');
const b = require('./module');

console.log(a === b); // true(同じオブジェクト)
キャッシュの確認

require.cache でキャッシュされたモジュールを確認できます。

キャッシュのクリア

delete require.cache[require.resolve('./module')] でキャッシュを削除できます(テストで使用されることがある)。

JSON の読み込み

CommonJS では JSON ファイルも直接 require できます。

const config = require('./config.json');
console.log(config.apiUrl);

require と module.exports のパターンを理解することで、既存の Node.js コードベースを読み解くことができます。