開発をしているとよく使う機能や関数、値などはモジュール化して掃き出しておきたいことがあると思います。 Node.js では module を使うことでそうしたことが実現できます。 ここでは、 module の具体的な作成方法と利用方法についてまとめます。
目次
基本的な使い方
module の 作成
module は 1ファイル として切り出して作成します。
作成したファイルにおいて module.exports
にモジュール化したいオブジェクトや関数を設定することで module が作成できます。
module.js
var say = function () { console.log('hello'); }; module.exports = say;
module の 利用
require
でモジュールファイルを指定すると module.exports
に設定されたオブジェクトや関数が取り出せます。
現在のJavaScriptから見た相対パスを指定します。
program.js
var say = require('./module.js'); say();
サンプルコード
以下ではサンプルコードを見ながら具体的な使い方を見ていきます。
といっても「利用するときは require("パス")
で呼び出し」
「作成するときは exports
または module.exports
に設定」を行うだけです。
複数メソッドのモジュール化
単純に作成した複数メソッドをモジュール化する例を以下に載せます。
複数のオブジェクトやメソッドを1つのモジュールにする場合、 exports
の プロパティ を増やして追加することで出力ができます。
foo.js
var circle = require("./circle.js"); console.log(`半径 4 の 円の面積 は ${circle.area(4)}`);
circle.js
const PI = Math.PI; exports.area = function (r) { return PI * r * r; } exports.circumference = function (r) { return 2 * PI * r; }
この例で var circle = require("./circle.js")
すると foo.js で以下のような コード を実行するのと同じ意味になります。
var circle = { "area": function (r) { return PI * r * r; }, "circumference": function (r) { return 2 * r * PI; } };
単一オブジェクトのモジュール化
単一のメソッドやクラスを出力する場合、 module.exports
に対して出力したいメソッドやクラスを設定します。
先の例であげた exports
に設定しても出力できません。
foo.js
var Square = require("./square.js"); var o = new Squre(2); console.log(`1辺 が 2 の 正方形の面積 は ${o.area()}`);
square.js
var Square = function (width) { this.width = width; }; Square.prototype.area = function () { return this.width * this.width; }; module.exports = Square;
この例の場合、 foo.js で実行している var Square = require("./square.js")
は以下のコードと同等になります。
var Square = function (width) { this.width = width; }; Square.prototype.area = function () { return this.width * this.width; };
[補足] module の 読み込み
読み込み順
パス Y
にあるモジュールで require(X)
を行った場合、以下のような読み込みを行います。
パス Y
にあるモジュールで require(X)
を実行
X
がコアモジュールの場合- コアモジュールを返します
- 終了
X
が./
、/
、../
で始まる場合- LOAD_AS_FILE(
Y
+X
) - LOAD_AS_DIRECTORY(
Y
+X
)
- LOAD_AS_FILE(
- LOAD_NODE_MODULES(
X
, dirname(Y
)) "not found"
の例外をスロー
LOAD_AS_FILE(X)
X
がファイルの場合、 JavaScript テキスト としてX
を読み込んで終了X.js
がファイルの場合、 JavaScript テキスト としてX.js
を読み込んで終了X.json
がファイルの場合、 JavaScript オブジェクト としてX.js
on を読み込んで終了X.node
がファイルの場合、 バイナリアドオン としてX.node
を読み込んで終了
LOAD_AS_DIRECTORY(X)
X/package.json
がファイルの場合X/parse.json
をパースし、main
フィールドの値を確認- LOAD_AS_FILE(
X/mainフィールドに指定されたファイル
)
X/index.js
がファイルの場合、X/index.js
を JavaScript として読み込んで終了X/index.json
がファイルの場合、X/index.json
を JavaScript として読み込んで終了X/index.node
がファイルの場合、X/index.node
を JavaScript として読み込んで終了
LOAD_NODE_MODULES(X, START)
- let DIRS = NODE_MODULES_PATHS(START)
- for each DIR in DIRS
- LOAD_AS_FILE( DIR/X )
- LOAD_AS_DIRECTORY( DIR/X )
NODE_MODULES_PATHS(START)
- let PARTS = path split(START)
- let I = count of PARTS - 1
- let DIRS = []
- while I >= 0,
- PARTS[I] が "node_modules" の場合、CONTINUE
- DIR = path join(PARTS[0 .. I] + "node_modules")
- DIRS = DIRS + DIR
- let I = I - 1
- return DIRS
キャッシュ
一度読み込まれたモジュールファイルはキャッシュされます。 複数回同じモジュールファイルを読み込もうとしても最初に読み込んだファイルのキャッシュを利用するので複数回読み込むことはありません。
参考記事
最後に… このブログに興味を持っていただけた方は、 ぜひ 「Facebookページ に いいね!」または 「Twitter の フォロー」 お願いします!!