Node.jsでモジュールを理解する:module.exportsとexportsの初心者向けチュートリアル

2024-04-09

Node.jsにおける「module.exports」と「exports」の違い:徹底解説

Node.jsにおいて、モジュールシステムはコードを分割し、再利用性を高める重要な機能です。モジュールを定義する際に、「module.exports」と「exports」という2つのオブジェクトが使われますが、混同されやすい点も存在します。

本記事では、「module.exports」と「exports」の詳細な違いを、分かりやすくかつ網羅的に解説します。

共通点

まず、「module.exports」と「exports」は、どちらもモジュールから外部に公開する値を格納するオブジェクトです。require() 関数を使ってモジュールを読み込む際、このオブジェクトが返されます。

具体的には、以下のような値を格納できます。

  • 関数
  • オブジェクト
  • プリミティブ値 (例:数値、文字列、ブール値)

重要な違い

一見似ている「module.exports」と「exports」ですが、実は以下の点で重要な違いがあります。

参照方法

  • module.exports: モジュールのスコープ内で直接参照できます。
  • exports: exports オブジェクト経由で参照する必要があります。
// module.exports を直接参照
module.exports = function() {
  console.log('module.exports function');
};

// exports オブジェクト経由で参照
exports.myFunction = function() {
  console.log('exports.myFunction');
};

書き換え可能性

  • exports: 基本的には書き換えられませんが、特殊なケースを除いて書き換えることは推奨されていません。
// module.exports を書き換える
module.exports = function() {
  console.log('module.exports function 1');
};

module.exports = function() {
  console.log('module.exports function 2'); // 上書き
};

優先順位

モジュール内で module.exportsexports を同時に使用した場合、module.exports の方が優先的に使われます。

// module.exports が優先される
exports.myVar = 1;
module.exports = { myVar: 2 };

// require() で取得される値
const mod = require('./myModule');
console.log(mod.myVar); // 2が出力

使い分けの指針

上記の説明に基づき、「module.exports」と「exports」を使い分ける際の指針を以下にまとめます。

  • 基本的には module.exports を使用する: 値を書き換えたり、モジュール内で直接参照したりする場合は、module.exports を使いましょう。
  • 特殊なケースでのみ exports を使用する: module.exports の参照を保持する必要があるなど、特殊なケースを除いては exports を使用する必要はありません。

まとめ

項目module.exportsexports
参照方法モジュールのスコープ内で直接参照可能exports オブジェクト経由で参照
書き換え可能性書き換え可能基本的には書き換え不可(特殊なケースを除く)
優先順位exports より優先
使い分け基本的には module.exports を使用する特殊なケースでのみ使用する

その他

  • 歴史的に exports が先に使われていましたが、現在では module.exports を推奨するのが一般的です。
  • コードの可読性向上のため、どちらか一方に統一して使用することが望ましいです。

これらの情報に加え、実際にコードを書いて試してみることで、より深い理解を得ることができます。




サンプルコード:module.exportsとexportsを使い分ける

基本的な使い方

// module1.js
// module.exports を使って関数を提供
module.exports = function myFunction() {
  console.log('myFunction called!');
};

// module2.js
// require() でモジュールを読み込み、exports経由で関数を利用
const mod1 = require('./module1');
mod1.myFunction(); // myFunction called!が出力

module.exportsで値を書き換える

// module3.js
// module.exports で値を書き換える
module.exports = 1;
module.exports = 2;

// module4.js
// require() でモジュールを読み込み、値を取得
const mod3 = require('./module3');
console.log(mod3); // 2が出力

exportsオブジェクトにプロパティを追加

// module5.js
// exportsオブジェクトにプロパティを追加
exports.myVar = 10;

// module6.js
// require() でモジュールを読み込み、exportsオブジェクトのプロパティを利用
const mod5 = require('./module5');
console.log(mod5.myVar); // 10が出力

module.exportsとexportsを同時に使用する

// module7.js
// module.exportsとexportsを同時に使用する
exports.myVar = 20;
module.exports = {
  myFunction: function() {
    console.log('myFunction called!');
  }
};

// module8.js
// require() でモジュールを読み込み、値と関数をそれぞれ利用
const mod7 = require('./module7');
console.log(mod7.myVar); // 20が出力
mod7.myFunction(); // myFunction called!が出力

これらのサンプルコードを通して、「module.exports」と「exports」の違いを理解し、適切に使い分けることができるようになりました。

補足

  • 上記のコードはあくまで基本的な例であり、実際の開発ではより複雑なモジュール構成になる可能性があります。
  • コードの可読性向上のため、コメントを適切に記述することをおすすめします。



Node.jsにおける「module.exports」と「exports」の代替方法

ES Modulesは、ブラウザやNode.jsを含むさまざまなJavaScriptランタイムで標準的にサポートされるモジュールシステムです。従来のCommonJSモジュールとは異なり、以下の利点があります。

  • より簡潔な構文: importexport キーワードを使用して値をエクスポート/インポートできます。
  • 依存関係の明確化: package.json ファイルを使用してモジュールの依存関係を宣言できます。
  • ツリーシェイキング: 使用していないコードが自動的に削除されます。

ES Modulesのサンプルコード

// module.js
// ES Modulesを使って関数を提供
export function myFunction() {
  console.log('myFunction called!');
}

// main.js
// import キーワードを使ってモジュールを読み込み、関数を利用
import { myFunction } from './module';
myFunction(); // myFunction called!が出力

その他の代替方法

  • クラス: クラスを使って値や関数をカプセル化することができます。
  • 関数: 関数オブジェクトを返して値や関数を提供することができます。

使い分け

  • 既存のプロジェクト: すでにCommonJSモジュールを使用しているプロジェクトの場合は、「module.exports」と「exports」を使い続けるのが一般的です。
  • 新規プロジェクト: 新規プロジェクトの場合は、ES Modulesの使用を検討することをおすすめします。

Node.jsモジュールで値をエクスポートするには、「module.exports」と「exports」以外にも、ES Modulesやクラス、関数などの方法があります。それぞれのメリットとデメリットを理解し、状況に応じて適切な方法を選択することが重要です。


javascript node.js commonjs


JavaScriptで「isNaN関数」と「正規表現」を使いこなして文字列の有効性を検証

Web 開発において、ユーザー入力の値を検証することは非常に重要です。特に、数値入力を扱う場合、誤った入力がアプリケーションの動作に悪影響を及ぼす可能性があります。そこで今回は、JavaScript で "文字列が有効な数値かどうか" を検証する方法について、分かりやすく解説します。...


フロントエンド開発の鬼門:正規表現による要素選択をjQueryでスッキリ解決

さらに、正規表現を使うことで、より複雑な条件を指定することができます。複雑な条件を指定できる要素の属性値の一部一致や前方一致、後方一致など、様々なパターンで検索できる動的な要素の選択に役立つjQueryセレクターで正規表現を使うには、filter()メソッドを使用します。...


iframeの謎を解き明かせ!JavaScript/jQueryで自由自在に操作する方法

iframeは、別のHTML文書を現在のページに埋め込むための要素です。JavaScript/jQueryを使用すると、iframeの内容にアクセスし、さまざまな操作を行うことができます。方法iframeの内容にアクセスするには、主に以下の方法があります。...


Express.js で GET リクエストのクエリ文字列から変数を取得する方法

req. query オブジェクトは、GET リクエストのクエリ文字列のパラメータをすべて含むオブジェクトです。 このオブジェクトを使って、個々のパラメータにアクセスすることができます。例:この例では、req. query. name と req...


npmでつまずかない!proxy.pacファイルで企業プロキシを乗り越えるテクニック

企業ネットワークでは、セキュリティ対策の一環として、インターネットアクセスをプロキシサーバー経由で制御している場合があります。このような環境で Node. js のパッケージ管理ツールである npm を利用する場合、プロキシ設定を適切に行う必要があります。...


SQL SQL SQL SQL Amazon で見る



Node.jsモジュール開発:module.exports vs exports の徹底解説

オブジェクトへの参照方法module. exports: モジュールオブジェクトのプロパティとして存在します。exports: 変数として存在し、module. exportsと同じオブジェクトを参照します。複数のオブジェクトを公開module