2011年12月20日 星期二

Nodejs + Express 的 Route 流程規劃

Standard
如大多數人的習慣,往往我們都把 Route 的路徑都定義在 app.js 當中。Express 所提供的眾多範例程式中,雖然有將 Route 抽出來放在 routes 目錄下的實作方式,但也太簡單,只支援一層的設計。這意味著,如果 routes 之下有更多子目錄,放著更多的 route 設定,都是不會被讀取的。

這邊做了簡單的修改,利用遞迴的做法,掃描所有的子目錄,然後去載入所有的 js 檔案以擴充 Route 的設定。

以下是 route.js 的程式碼:
var vm = require('vm');
var fs = require('fs');

module.exports = function(app) {
  var dir = __dirname + '/routes';
  var context = {
    app: app,
    require: require
  };
  var newContext;

  /* Initializing Context */
  for (var key in global)
    context[key] = global[key];

  newContext = vm.createContext(context);

  /* Loading all routes */
  loadRouteDir(newContext, dir);
};

function loadRouteDir(context, path) {
  /* Scanning files */
  fs.readdirSync(path).forEach(function(file) {
    loadRouteFile(context, path, file);
  });
}

function loadRouteFile(context, path, file) {
  var fullpath = path + '/' + file;

  fs.stat(fullpath, function(err, stats) {
    if (stats.isFile()) {
      /* Loading route */
      var str = fs.readFileSync(fullpath, 'utf8');
      vm.runInContext(str, context, file);
    } else if (stats.isDirectory()) {
      /* Loading sub-directory */
      loadRouteDir(context, fullpath);
    }
  });
}

在 app.js 中只要這樣使用即可:
/* app is Express Server  */
require('./route')(app);