28

Expressを使用してNode.jsでプロジェクトを行っています。これが私のディレクトリ構造です:

root
|-start.js
|-server.js
|-lib/
|    api/
|        user_getDetails.js
|        user_register.js

lib/api/ディレクトリには、API に関連する多数の JS ファイルがあります。私がする必要があるのは、API 関数の 1 つが高速 HTTP サーバーから要求されるたびに、対応する API ハンドラーで指定されたアクションを実行する、一種のフック システムを作成することです。ややこしいかもしれませんが、ご理解いただければ幸いです。

  1. Larry は、ユーザーの詳細を取得するために POST 経由で要求を送信します。
  2. サーバーは、lib/apiその要求に関連付けられた機能を見つけるために調べます。
  3. サーバーはアクションを実行し、データを Larry に送り返します。

うまくいけば、あなたは私を助けることができます. プロトタイプを使えばできると思っていたのですが、よくわかりません。

ありがとう!

4

3 に答える 3

34

スクリプトの場所がわかっている場合、つまり のような初期ディレクトリがある場合は、次のDIRように を操作できますfs

サーバー.js

var fs = require('fs');
var path_module = require('path');
var module_holder = {};

function LoadModules(path) {
    fs.lstat(path, function(err, stat) {
        if (stat.isDirectory()) {
            // we have a directory: do a tree walk
            fs.readdir(path, function(err, files) {
                var f, l = files.length;
                for (var i = 0; i < l; i++) {
                    f = path_module.join(path, files[i]);
                    LoadModules(f);
                }
            });
        } else {
            // we have a file: load it
            require(path)(module_holder);
        }
    });
}
var DIR = path_module.join(__dirname, 'lib', 'api');
LoadModules(DIR);

exports.module_holder = module_holder;
// the usual server stuff goes here

ここで、スクリプトは次の構造に従う必要があります (require(path)(module_holder)行のため)。たとえば、次のようになります。

user_getDetails.js

function handler(req, res) {
    console.log('Entered my cool script!');
}

module.exports = function(module_holder) {
    // the key in this dictionary can be whatever you want
    // just make sure it won't override other modules
    module_holder['user_getDetails'] = handler;
};

そして今、リクエストを処理するときは、次のことを行います。

// request is supposed to fire user_getDetails script
module_holder['user_getDetails'](req, res);

これにより、すべてのモジュールがmodule_holder変数にロードされます。私はそれをテストしませんでしたが、動作するはずです (エラー処理を除く!!! )。この機能を変更したくなるかもしれませんが (例えばmodule_holder、1 レベルの辞書ではなく、ツリーを作成するなど)、アイデアは理解できると思います。

この関数は、サーバーの起動ごとに1回ロードする必要があります(より頻繁に起動する必要がある場合は、おそらく動的なサーバー側のスクリプトを扱っているため、これはばかげたアイデアです)。ここで必要なのは、オブジェクトをエクスポートmodule_holderして、すべてのビュー ハンドラーが使用できるようにすることだけです。

于 2012-06-06T13:43:05.083 に答える
7

app.js

var c_file = 'html.js';

var controller = require(c_file);
var method = 'index';

if(typeof controller[method] === 'function')
    controller[method]();

html.js

module.exports =
{
    index: function()
    {
        console.log('index method');
    },
    close: function()
    {
        console.log('close method');    
    }
};

このコードを少し動的にすると、魔法のようなことができます:D

于 2012-09-04T08:56:02.993 に答える