Node.js
モジュールのエクスポートと使用
サーチ…
備考
Node.jsのすべては一般的に非同期で行われますが、 require()
はそれらのものの1つではありません。モジュールは実際には一度しかロードする必要がないため、ブロック動作であり、正しく使用する必要があります。
モジュールは、ロードされた後にキャッシュされます。開発中のモジュールを編集する場合は、新しい変更を使用するためにモジュールキャッシュ内のそのエントリを削除する必要があります。つまり、たとえモジュールがモジュールキャッシュからクリアされても、モジュール自体はガベージコレクションされないため、運用環境での使用には注意が必要です。
モジュールのロードと使用
モジュールはrequire()
関数によって "import"されるか、そうでなければ " require()
"されます。たとえば、Node.jsに同梱されているhttp
モジュールをロードするには、次のようにします。
const http = require('http');
ランタイムに同梱されているモジュールの他に、npmからインストールしたモジュール(expressなど)を要求することもできます。 npm install express
システムにインストールしていた場合は、次のように書くだけです。
const express = require('express');
また、アプリケーションの一部として自分で作成したモジュールを含めることもできます。この場合、現在のファイルと同じディレクトリにlib.js
という名前のファイルを含めるには、次のようにします。
const mylib = require('./lib');
拡張子を省略することができ、 .js
が引き継がれることに注意してください。モジュールをロードすると、変数には、必要なファイルから発行されたメソッドとプロパティを含むオブジェクトが読み込まれます。完全な例:
const http = require('http');
// The `http` module has the property `STATUS_CODES`
console.log(http.STATUS_CODES[404]); // outputs 'Not Found'
// Also contains `createServer()`
http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('<html><body>Module Test</body></html>');
res.end();
}).listen(80);
hello-world.jsモジュールの作成
Nodeは、関数と変数を他のファイルに公開するmodule.exports
インターフェイスを提供します。これを行う最も簡単な方法は、最初の例に示すように、1つのオブジェクト(関数または変数)のみをエクスポートすることです。
hello-world.js
module.exports = function(subject) {
console.log('Hello ' + subject);
};
エクスポート全体を単一のオブジェクトにしたくない場合、関数と変数をexports
オブジェクトのプロパティとしてエクスポートできます。以下の3つの例はすべて、これをわずかに異なる方法で示しています。
- hello-venus.js:関数の定義は別々に行われ、
module.exports
プロパティとして追加されます - hello-jupiter.js:関数定義は
module.exports
のプロパティの値として直接入力されます - hello-mars.js:関数定義は、
exports
プロパティとして直接宣言されています。これは、短いバージョンのmodule.exports
hello-venus.js
function hello(subject) {
console.log('Venus says Hello ' + subject);
}
module.exports = {
hello: hello
};
hello-jupiter.js
module.exports = {
hello: function(subject) {
console.log('Jupiter says hello ' + subject);
},
bye: function(subject) {
console.log('Jupiter says goodbye ' + subject);
}
};
hello-mars.js
exports.hello = function(subject) {
console.log('Mars says Hello ' + subject);
};
ディレクトリ名を含むモジュールの読み込み
hello
という名前のディレクトリがあり、次のファイルが含まれています。
index.js
// hello/index.js
module.exports = function(){
console.log('Hej');
};
main.js
// hello/main.js
// We can include the other files we've defined by using the `require()` method
var hw = require('./hello-world.js'),
hm = require('./hello-mars.js'),
hv = require('./hello-venus.js'),
hj = require('./hello-jupiter.js'),
hu = require('./index.js');
// Because we assigned our function to the entire `module.exports` object, we
// can use it directly
hw('World!'); // outputs "Hello World!"
// In this case, we assigned our function to the `hello` property of exports, so we must
// use that here too
hm.hello('Solar System!'); // outputs "Mars says Hello Solar System!"
// The result of assigning module.exports at once is the same as in hello-world.js
hv.hello('Milky Way!'); // outputs "Venus says Hello Milky Way!"
hj.hello('Universe!'); // outputs "Jupiter says hello Universe!"
hj.bye('Universe!'); // outputs "Jupiter says goodbye Universe!"
hu(); //output 'hej'
モジュールキャッシュの無効化
開発中に、同じモジュールに対してrequire()
を複数回使用すると、そのファイルに変更を加えたとしても、常に同じモジュールが返されることがあります。これは、モジュールが最初にロードされたときにモジュールがキャッシュされ、以降のモジュールのロードがキャッシュからロードされるためです。
この問題を回避delete
には、キャッシュ内のエントリをdelete
必要があります。たとえば、モジュールをロードした場合は次のようになります。
var a = require('./a');
その後、キャッシュエントリを削除することができます:
var rpath = require.resolve('./a.js');
delete require.cache[rpath];
そして、再度モジュールを要求する:
var a = require('./a');
このdelete
は、ロードされたデータ自体ではなく、ロードされたモジュールへの参照のみを削除するため、これは実稼働環境ではお勧めできません。モジュールはガベージコレクションされていないため、この機能を不適切に使用するとメモリがリークする可能性があります。
独自のモジュールを構築する
また、オブジェクトを参照して公開し、そのオブジェクトにメソッドを継続的に追加することもできます。
const auth = module.exports = {}
const config = require('../config')
const request = require('request')
auth.email = function (data, callback) {
// Authenticate with an email address
}
auth.facebook = function (data, callback) {
// Authenticate with a Facebook account
}
auth.twitter = function (data, callback) {
// Authenticate with a Twitter account
}
auth.slack = function (data, callback) {
// Authenticate with a Slack account
}
auth.stack_overflow = function (data, callback) {
// Authenticate with a Stack Overflow account
}
これらのモジュールを使用するには、モジュールを通常どおりに使用する必要があります。
const auth = require('./auth')
module.exports = function (req, res, next) {
auth.facebook(req.body, function (err, user) {
if (err) return next(err)
req.user = user
next()
})
}
すべてのモジュールが1回のみ注入される
NodeJSは、初めて必要なときにのみモジュールを実行します。さらに必要な関数は、同じObjectを再利用するため、別の時間にモジュール内のコードを実行しません。また、ノードはrequireを使用してロードされたモジュールを最初にキャッシュします。これにより、ファイルの読み込み回数が減り、アプリケーションの処理速度が向上します。
myModule.js
console.log(123) ;
exports.var1 = 4 ;
index.js
var a=require('./myModule') ; // Output 123
var b=require('./myModule') ; // No output
console.log(a.var1) ; // Output 4
console.log(b.var1) ; // Output 4
a.var2 = 5 ;
console.log(b.var2) ; // Output 5
node_modulesからのモジュールのロード
モジュールは、相対パスを使用せずに、 node_modules
という特別なディレクトリに置くことによってdをrequire
ことができます。
たとえば、ファイルindex.js
からfoo
というモジュールをrequire
するには、次のディレクトリ構造を使用できます。
index.js
\- node_modules
\- foo
|- foo.js
\- package.json
モジュールは、 package.json
ファイルと共にディレクトリの中に配置する必要があります。 package.json
ファイルのmain
フィールドは、モジュールのエントリポイントを指す必要があります。これは、ユーザーがrequire('your-module')
ときにインポートされるファイルrequire('your-module')
です。 main
デフォルトindex.js
提供されていない場合。あるいは、 require
呼び出しへの相対パスを追加するだけで、モジュールに関連するファイルを参照することができます: require('your-module/path/to/file')
。
モジュールは、 node_modules
ディレクトリからファイルシステム階層までのdをrequire
こともできます。私たちが次のディレクトリ構造を持っているなら、
my-project
\- node_modules
|- foo // the foo module
\- ...
\- baz // the baz module
\- node_modules
\- bar // the bar module
require('foo')
を使ってbar
内の任意のファイルからモジュールfoo
をrequire
することができます。
nodeはファイルシステム階層内のファイルに最も近いモジュール(ファイルの現在のディレクトリ/ node_modules)からのみ一致することに注意してください。ノードは、この方法でファイルシステムのルートまでのディレクトリを照合します。
npmレジストリまたは他のnpmレジストリから新しいモジュールをインストールするか、独自のものを作ることができます。
モジュールとしてのフォルダ
モジュールは、同じフォルダ内の多数の.jsファイルに分割できます。 my_moduleフォルダ内の例:
function_one.js
module.exports = function() {
return 1;
}
function_two.js
module.exports = function() {
return 2;
}
index.js
exports.f_one = require('./function_one.js');
exports.f_two = require('./function_two.js');
このようなモジュールは、フォルダ名で参照されます:
var split_module = require('./my_module');
必要な場合は、require関数の引数から./
またはフォルダへのパスの指示を省略してnode_modulesフォルダからモジュールをロードしようとします。
あるいは、同じフォルダにpackage.json
ファイルを次の内容で作成することもできます。
{
"name": "my_module",
"main": "./your_main_entry_point.js"
}
このようにして、メインモジュールファイル "index"に名前を付ける必要はありません。