簡體   English   中英

Node.JS:處理大型節點應用程序的多個模塊時出現問題

[英]Node.JS: issue with handling multiple modules for large node application

我是Node.JS的新手,因此開始尋找最佳實踐文章等,以確保我的node.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中做到這一點的干凈方法。

使用帶有express.Router()子路由器進行粒度化和封裝。 然后,每個路由器都將成為其自己的模塊,您可以插入該模塊中,從而不必在app.js顯式添加每個路由。

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_IDPOST/user 如果要將子路由移動到其他地方,這也很簡單,因為為用戶路由定義的方法是相對的。

我也有一個名為campaign_service的大型企業應用程序,其中包含許多模塊。

這就是我將路徑組織在文件campaign_router.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

重點:

  • 所有廣告系列功能均進入另一個名為campaign_manager.js的js文件(這是一種中間件)
  • 所有有效負載轉換器都進入一個名為“ converters”的子文件夾,並且該文件夾包含許多名為“ qs_converter.js”,“ json_converter.js”,...等等的文件。
  • 我的應用在接受任何廣告系列請求之前執行身份驗證,因此路由中已加載了中間件。
  • 如果除“ / campaigns”外還有其他掛載點,我將創建另一個路由器模塊並定義其他.js文件。 _我將使用index.js(或app.js)來加載這些路由器。

從本質上講,將代碼縮放為多個模塊並通過路由器文件導入它們對我來說非常容易。

編輯添加了使用場景Index.js

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM