requireした側の変数やオブジェクトをrequireされた側で操作する方法

Node.jsでモジュールを読み込んだ側(require()するソース)にある変数やオブジェクトを読み込まれた側(require()されるソース)で参照する方法です。
module.exportsrequire.main.exportsを使うことで、モジュールを読み込んだ側にある変数を呼び出された側で参照・操作できます。

require.mainにはNode.jsでメインとなるファイル(エントリーポイント)が設定されています。
require.main.exportsは、エントリーポイントがエクスポートしたオブジェクトを参照するための特殊な変数です。

Expressを使う

Expressmodule.exportsに設定し、app.set()app.get()を使って値を参照します。

値型を設定する

app.set()はコールした時点の値になります。そのため、app.set()後に呼び出し側で値を更新しても反映されません。

required.js
exports.func = (request, response) => {
    const app = require.main.exports;
    console.log(app.get('count'));
};

最初に1回だけ設定した場合

app.js
"use strict";

const express = require('express');
const required = require('./required.js');

const app = express();
module.exports = app;

let count = 1;
app.set('count', count);

app.listen(8080, () => {
    console.log('listening at http://localhost:8080');
});

app.get("/", (request, response) =>{
    required.func(request, response);
    count++;
    response.send('count up');
});
実行結果

http://localhost:8080へアクセス1回目 > 1
http://localhost:8080へアクセス2回目 > 1

都度設定する場合

app.set()を毎回行えば値の更新は可能ですが、required.js側で値の更新は行えません。

app.js
"use strict";

const express = require('express');
const required = require('./required.js');

const app = express();
module.exports = app;

let count = 1;

app.listen(8080, () => {
    console.log('listening at http://localhost:8080');
});

app.get("/", (request, response) =>{
    app.set("count", count);
    required.func(request, response);
    count++;
    response.send('count up');
});
実行結果

http://localhost:8080へアクセス1回目 > 1
http://localhost:8080へアクセス2回目 > 2

オブジェクトを設定する

required.jsでも値を更新したい場合は、app.set()でオブジェクトを設定し、メンバーを更新するようにします。

required.js
exports.func = (request, response) => {
    const app = require.main.exports;
    let container = (app.get('Container'));
    console.log(container.count);
    container.count++;
    response.send('count up');
};
app.js
"use strict";

const express = require('express');
const required = require('./required.js');

const app = express();
module.exports = app;

const container = {};
container.count = 1;
app.set("Container", container);

app.listen(8080, () => {
    console.log('listening at http://localhost:8080');
});

app.get("/", required.func);

実行結果

http://localhost:8080へアクセス1回目 > 1
http://localhost:8080へアクセス2回目 > 2

Expressを使わない方法

module.exportsで変数を定義すると、app.set()しなくても参照できます。また、オブジェクトではなく値型でも更新できます。

required.js
exports.func = (request, response) => {
    let container = require.main.exports.container;
    console.log(`require.main.exports.container.count=${container.count}`);
    container.count++;
    require.main.exports.count++;
    let count = require.main.exports.count;
    console.log(`require.main.exports.count=${count}`);
    response.send('count up');
};
app.js
"use strict";

const express = require('express');
const required = require('./required.js');

let count = 100;

const app = express();
module.exports.container = { count: 1, };
module.exports.count = count;

app.listen(8080, () => {
    console.log('listening at http://localhost:8080');
});

app.get("/", required.func);

実行結果

http://localhost:8080へアクセス1回目

require.main.exports.container.count=1
require.main.exports.count=101

http://localhost:8080へアクセス2回目

require.main.exports.container.count=2
require.main.exports.count=102

まとめ

個人的にはmodule.exports.変数名を使うかな。で、Expressのroute メソッドではExpressに依存すると思うので、module.exports.express = app;として、route メソッドconst app = require.main.exports.express;として使うのが分かりやすい(気がする)。

参考

このエントリーをはてなブックマークに追加
にほんブログ村 IT技術ブログへ

スポンサードリンク

関連コンテンツ

コメント

メールアドレスが公開されることはありません。 が付いている欄は必須項目です