2016-09-12 13 views
0

私はNode.JSの初心者です。node.jsコードが単体テストに適していることを確認するためのベストプラクティス記事などを探し始めました。 .jsベストプラクティスNode.JS:大規模ノードアプリケーション用に複数のモジュールを処理する際の問題

app.js:

module.exports = function (flights) { 
    var express = require('express'); 
    var routes = require('./routes')(flights); 
    var path = require('path'); 
    var app = express(); 

    // all environments 
    app.set('port', process.env.PORT || 3000); 
    app.set('views', __dirname + '/views'); 
    app.set('view engine', 'jade'); 
    app.use(express.favicon()); 
    app.use(express.logger('dev')); 
    app.use(express.bodyParser()); 
    app.use(express.methodOverride()); 
    app.use(function (req, res, next) { 
     res.set('X-Powered-By', 'Flight Tracker'); 
     next(); 
    }); 
    app.use(app.router); 
    app.use(express.static(path.join(__dirname, 'public'))); 

    // development only 
    if ('development' == app.get('env')) { 
     app.use(express.errorHandler()); 
    } 

    app.get('/flight/:number', routes.flight); 
    app.put('/flight/:number/arrived', routes.arrived); 
    app.get('/list', routes.list); 

    return app; 
} 

server.js:

var http = require('http'), 
    flights = require('./data'), 
    app = require('./app')(flights); 

http.createServer(app).listen(app.get('port'), function(){ 
    console.log('Express server listening on port ' + app.get('port')); 
}); 

モジュール(index.js):

var Flight = function() { 
    this.data = { 
     number: null, 
     origin: null, 
     destination: null, 
     departs: null, 
     arrives: null, 
     actualDepart: null, 
     actualArrive: null 
    }; 

    this.fill = function (info) { 
     for(var prop in this.data) { 
      if(this.data[prop] !== 'undefined') { 
       this.data[prop] = info[prop]; 
      } 
     } 
    }; 

    this.triggerDepart = function() { 
     this.data.actualDepart = Date.now(); 
    }; 

    this.triggerArrive = function() { 
     this.data.actualArrive = Date.now(); 
    }; 

    this.getInformation = function() { 
     return this.data; 
    }; 
}; 

module.exports = function (info) { 
    var instance = new Flight(); 

    instance.fill(info); 

    return instance; 
}; 

研究しながら私は、次のコード例に出くわしましたルート(index.js):

module.exports = function (flights) { 
    var flight = require('../flight'); 

    for(var number in flights) { 
     flights[number] = flight(flights[number]); 
    } 

    var functions = {}; 

    functions.flight = function(req, res){ 
     var number = req.param('number'); 

     if (typeof flights[number] === 'undefined') { 
      res.status(404).json({status: 'error'}); 
     } else { 
      res.json(flights[number].getInformation()); 
     } 
    }; 

    functions.arrived = function (req, res) { 
     var number = req.param('number'); 

     if (typeof flights[number] === 'undefined') { 
      res.status(404).json({status: 'error'}); 
     } else { 
      flights[number].triggerArrive(); 
      res.json({status: 'done'}); 
     } 
    }; 

    functions.list = function (req, res) { 
     res.render('list', { 
      title: 'All Flights', 
      flights: flights}); 
    }; 

    return functions; 
}; 

これはどのように構成されているのが好きですが、このシナリオでは複数のモジュールを効率的に処理する方法はありません。 User、Initeraryなどのモジュールが追加されているとしましょう。app.jsファイルに経路を追加するようになったので、これは混乱するように思えます。app.jsに渡す必要のあるパラメータの数。 20個以上のモジュールを必要とする大きなレストレイヤがあるとどうなりますか?私はnode.jsでこれを行う必要がある、きれいな方法を示す文書やリンクや例を探しています。

答えて

0

express.Router()でサブルータを使用してグラニュライゼーションし、カプセル化します。それぞれのルータはそれ自身のモジュールになり、それを作成する際に引き出して、に明示的にすべてのルートを追加する必要はありません。

user.jsの

"use strict"; 

// Create a router 
var express = require("express"), 
    router = express.Router(); 

router.get("/", function (req, res, next) { 
    // All your User logic 
    res.send([ 
     { 
      name: "Bob" 
     }, 
     { 
      name: "John" 
     } 
    ]); 
}); 

router.get("/:number", function (req, res, next) { 
    res.send({ 
     name: "Bob" 
    }); 
}); 

router.post("/", function (req, res, next) { 
    res.send({ 
     name: "New Guy" 
    }); 
}); 

module.exports = router; 

App.js

var app = express(); 
app.use("/user", require("./User")); 

今することができますGET/userGET/user/SOME_ID、および/userからPOST。ユーザールートに定義されたメソッドが相対的なので、サブルートをどこかに移動したい場合は、単純です。

+0

を持っていますか? – user1790300

+0

@ user1790300私の編集を参照してください。 – zero298

+0

はい、うまいです。感謝万円。 – user1790300

0

私もcampaign_serviceという大規模なエンタープライズアプリケーションを持っています。これは、多くのモジュールから構成されています。

これはどのようにして、私はcampaign_router.jsファイルにルートを整理します。すべてのペイロードコンバータは "と呼ばれるサブフォルダに移動

  • すべてのキャンペーン機能、(ミドルウェアである)別のJSファイルに入る、と呼ばれるcampaign_manager.js
  • var express = require('express'); 
    var router = express.Router(); 
    var cm = require('./campaign_manager.js'); 
    var qsc = require('./converters/qs_converter.js'); 
    var jsc = require('./converters/json_converter.js'); 
    var xmlc = require('./converters/xml_converter.js'); 
    var fc = require('./converters/f_converter'); 
    var fc2 = require('./converters/fjt2_converter'); 
    var cv = require('./campaign_validator.js'); 
    var templates = require('./template_list.js'); 
    var AuthDecoder = require('authdecoder'); 
    var adc = AuthDecoder.middleware; 
    
    router.get ('/campaigns/qs',  qsc, adc, cv, cm.createCampaign);  // Creates a new campaign using query string params 
    router.post ('/campaigns/b/xml', xmlc, adc, cv, cm.createCampaign);  // Creates a new campaign using xml payload 
    router.post ('/campaigns/file', fc, adc, cv, cm.createCampaign);  // Creates a new campaign using uploaded file 
    router.post ('/campaigns/file/type2', fc2, adc, cv, cm.createCampaign); // Creates a new campaign using uploaded file 
    router.post ('/campaigns/js',  jsc, adc,cv, cm.createCampaign);  // Creates a new bulk campaign using json payload 
    router.get ('/campaigns/',  adc, cm.getCampaigns);     // Returns a list of bulk campaigns accessible for the invoking user. 
    router.get ('/campaigns/date', adc, cm.getCampaignsByRange);   // Returns a list of bulk campaigns accessible for the invoking user. 
    router.get ('/campaigns/b/:id', adc, cm.getCampaign);     // returns the details of a specific campoaign 
    router.put ('/campaigns/b/id', cm.updateCampaign);      // Updates a specified campaign 
    router.delete ('/campaigns/b/:id', cm.deleteCampaign);      // deletes a campaign 
    router.post ('/pause',   adc, cm.pauseJob);      // Pauses an ongoing campaign 
    router.post ('/resume',   adc, cm.resumeJob);      // Resumes a paused campaign 
    router.post ('/cancel',   adc,cm.cancelJob);      // Resumes a paused campaign 
    //router.post ('/reschedule',  adc,cm.rescheduleCampaign);    // Resumes a paused campaign 
    //router.get ('/',     cm.pingCampaignServer);  
    router.get ('/templates',  adc, templates.listTemplates);   // gives the campaign server templates 
    

    要点このフォルダには「qs_converter.js」、「json_converter.js」、...、blah blahというファイルがたくさんあります。

  • 私のアプリは、キャンペーンリクエストが承認される前に認証を実行するため、ルートにミドルウェアが読み込まれています。
  • "/ campaigns"以外のマウントポイントがある場合は、別のルータモジュールを作成し、追加の.jsファイルを定義します。 _これらのルータをロードするには、index.js(またはapp.js)を使用します。

私のコードを複数のモジュールに拡大縮小し、ルータファイル経由でインポートすることは、基本的には非常に簡単です。あなたは、これがどのように見えるかのいずれかのサンプルコードを

EDIT を追加しました使用シナリオ Index.js

var routes = require('./campaign_router.js'); 
... 
app.use('/campaignservice', routes); 
+0

このシナリオでは、どのファイルがcampaign_router.jsにアクセスしますか?私はここで初心者であることをお詫びします。 – user1790300

+0

index.js。あなたの場合は、app.jsか、最初のエントリーポイントファイルであってもかまいません。 –

関連する問題