Node.js でのモジュールとエクスポートの方法

Node.js のモジュールとパッケージとは

Node.js でコードを書く利点の1つには、外部のモジュールを取り込むのが簡単であることが挙げられます。

Node.js には Node パッケージマネージャ (node package manager, npm) が含まれています。これを使うと、 インターネット上に公開されているモジュールを自分のプロジェクトに取り込むことが簡単です。

パッケージマネージャのコマンドは Node Package Manager の頭文字をとって、npm という名前のコマンドです。

例えば、express というパッケージを取り込むには、次のコマンドを実行するだけです。

npm install express

Node.js では、それぞれの JavaScript ファイルはモジュールという単位として認識されます。

通常ひとつの機能は複数のファイル (モジュール) で実装されていて、外部からある機能を取り込むとなれば複数のファイルが必要になります。この機能毎のまとまりのことを パッケージ といいます。

module の取り込み

Node.js 上で実行される JavaScript はモジュール毎に (つまり JavaScript ファイル毎に)、module オブジェクトを持っています。

試しに index.js に次の一行だけ書いて実行してみましょう。

console.log(module);

これを実行すると、次の結果になります。

node index.js
Module {
  id: '.',
  exports: {},
  parent: null,
  filename: '/Users/user1/Src/nodejs/test1/index.js',
  loaded: false,
  children: [],
  paths:
   [ '/Users/user1/Src/nodejs/test1/node_modules',
     '/Users/user1/Src/nodejs/node_modules',
     '/Users/user1/Src/node_modules',
     '/Users/user1/node_modules',
     '/Users/node_modules',
     '/node_modules' ] }

さて、この出力をよく見るとこのモジュールオブジェクトが exports というプロパティを持っていることがわかります。

module.exports の使い方

この exports プロパティは、あるモジュールを他のモジュールから参照させたいときに活躍します。

例えば foo.js を次のようにします。

module.exports.func1 = function() {
    console.log('Hello!');
}

module.exports.person = {
    age: 25,
    name: 'Tokyo Taro',
    title: 'Manager'
}

これは module オブジェクトの exports プロパティにセットされている空のオブジェクトに、 func1 というプロパティを作成して、それにファンクションオブジェクトを1つ設定し、 さらに、person というプロパティにオブジェクトをセットしています。

これを index.js から使うには次のようにします。

foo = require('./foo');

foo.func1();
console.log(foo.person);

この実行結果は次の通りです。

node index.js
Hello!
{ age: 25, name: 'Tokyo Taro', title: 'Manager' }

Node 上で他のモジュールを取り込むには、require を使います。

require で取り込むモジュールを指定するとき、./ などのようにパスを指定すると、 相対パスとして認識します。一方、そうでない場合は node_modules という名前のディレクトリ内からその名前のパッケージを探します。

さて、モジュールを require で取り込んだら、取り込んだ先の module.exports が渡されます。

これによって、取り込んだ側では exports にセットされた関数やら、オブジェクトを参照することができます。

exports 変数の使い方

モジュールでは module.exports と書く代わりに、 exports という変数も使えることになってます。これは module.exports への参照です。

例えば上の例では、次のように書いたのと同様になります。

exports.func1 = function() {
    console.log('Hello!');
}

exports.person = {
    age: 25,
    name: 'Tokyo Taro',
    title: 'Manager'
}

注意点としては、exports はあくまでも module.exports への参照として使えるものだという点です。 もし、exports に他のオブジェクトをセットしてしまうと、module.exports を参照できなくなります。

もし、オブジェクトを丸ごとセットしたい場合は、次のようにかけば上記と同様のことが実現できます。

module.exports = {
  func1: function() {
    console.log('Hello!');
  },
  person: {
    age: 25,
    name: 'Tokyo Taro',
    title: 'Manager'
  }
};

しかし、もし module.exports = ... ではなく、 exports = ... と書いて、上のようにオブジェクトをセットしてしまうと、 (module.exports への参照ではなくなってしまうので) module.exports に正しく値がセットされず、期待通り動作しなくなります。

無用な混乱を招くくらいなら、常に module.exports とフルネームで書くのが良いでしょう。 もともとその値を更新したいわけですから。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Node.js 入門