Express.js的外部配置

时间:2013-01-24 17:07:21

标签: node.js express

我正在使用Express.js构建一个小型Node应用程序,为了尽可能保持我的server.js文件干净,我想在外部文件中构建我的配置。以下是服务器的外观:

// server.js
var express = require( 'express' );
var app = express();
app.enable( 'trust proxy' );

// Set application config params
require( './config.js' )( app, express );

// Load routes and start listening...
require( './routes' )( app );
app.listen( app.get( 'port' ) );

我的config.js文件设置了一些默认值,然后更新或覆盖NODE_ENV特定配置功能中的配置。除了讨厌的时机,一切都会好的。

我的路由需要访问某些配置值。有没有办法确保我的路由被加载,我的服务器启动只在配置完全加载后才开始只监听?还有更好的方法吗?

我得到了事件循环,但我是对节点/快递的新品牌,所以我几乎可以接受任何事情。根据我在各种文章或文档资料中阅读的经验,我依旧将我想知道的事情拼凑在一起。我不认为我太偏离这里,但也许这过于乐观了。

更新

我的config.js

module.exports = function( app, express ) {
  var config = this;

  app.configure( function() {
    app.set( 'port', 3000 );
    app.set( 'datasources',   {
      'api'   : {...},
      'mysql' : {...}
    });
    app.use( express.logger() );
    app.use( express.bodyParser() );
    app.use( express.cookieParser() );
    app.use( express.methodOverride() );
    app.use( app.router );
  });

  // dev-specific config
  app.configure( 'development', function() {
    console.log( 'Loading development configuration' );

    app.use( express.errorHandler({ dumpExceptions: true, showStack: true }) );

    // update the mysql config with a connection object
    var datasources = app.get( 'datasources' );
    var mysqlConnection = require( 'mysql' ).createConnection({...});
    datasources.mysql.connection = mysqlConnection;

    app.set( 'datasources', datasources );
  });

  // stg-specific config
  app.configure( 'staging', function() {
    console.log( 'Loading staging configuration' );

    app.use( express.errorHandler() );

    // update the mysql config with a connection object
    var datasources = app.get( 'datasources' );
    var mysqlConnection = require( 'mysql' ).createConnection({...});
    datasources.mysql.connection = mysqlConnection;

    app.set( 'datasources', datasources );
  });


  // prd-specific config
  app.configure( 'production', function() {
    console.log( 'Loading production configuration' );
    app.use( express.errorHandler() );
  });


  console.log( app.get( 'datasources' ) );
  console.log( 'Configuration loaded' );

  return config;
};

3 个答案:

答案 0 :(得分:2)

为config.js模块分配回调,让它看起来像

require( './config.js' )( app, express, finish );
var finish = function(){
    // Load routes and start listening...
   require( './routes' )( app );
   app.listen( app.get( 'port' ) );
}

在你的配置方法中,使用像async之类的模块,并使所有加载在最后同步并回调函数。例如:

**config.js**
module.exports = function(app,express,finish){
    function loadConfig1(cb){
        fs.readFile("....", function(){ // Or someother else async function
              ...  if succesfull, cb(null);
              ...  if fail, cb("error!!!!");
         });
    }
    ....
    function complete(err, results){
         if (!err){
            finish(); // you guarantee that all the functions are completed succesfully
         }
    }
}

答案 1 :(得分:2)

如果配置中的代码全部是同步的,那么这应该有效:

// server.js
var express = require( 'express' );
var app = express();
var config = require( './config.js' );  // load config
app.enable( 'trust proxy' );

// -----------------------------------------------
// If the code inside your config is all synchronous this call 
// will block, which is what you want.
config(app, express );

// Load routes and start listening...
require( './routes' )( app );
app.listen( app.get( 'port' ) );

答案 2 :(得分:-1)

我目前正致力于Express的扩展,它允许纯json外部路由配置。我打算在不久的将来开源这个项目。如果有人有兴趣,我很乐意通过Github和NPM分享这个项目的早期预览

module.exports = {
  /**
   * settings
   */
  config:{
    "controller_directory" : "routes"
  },

  /**
   * defaults to ./routes directory
   */
  filters: {
    secure: "secure.securityListener",
    global:"secure.globalListener"
  },
  /**
   * defaults to ./routes directory
   * order matters for filters
   * filters should always contain a path which calls next();
   * router should be the final destination to a request
   *
   * possible verbs are [use, all, get, post, delete ...]
   * "use" is the default, "mount" path is stripped and is not visible to the middleware function.
   * other verbs will not strip out the "mount" path
   */
  routes: {
    global: {"filters": ["global"]},
    index:{path:"/", "controller": "index"},
    users:{path:"/users", "controller": "users", "filters": ["secure"]},
    prices:{path:"/prices", "controller": "prices"},
    software:{path:"/software", "controller": "software"},
    auth:{path:"/auth", "controller": "secure.onAuthentication", "verb": "get"}
  }

};