2014-11-21 102 views
0

我開始了一個新的節點項目,並想動態地添加路由。我之前做過這些,但從來沒有深入過一層文件夾。 爲此,我想出了一個遞歸函數來添加路線並遍歷可能的子文件夾。該函數在我的app.js中調用。該項目的文件夾看起來是這樣的:nodejs express遞歸路由失敗(404)

app.js 
routes/ 
    index.js 
    users.js 
    api/ 
     foo.js 
     test/ 
      bar.js 

在app.js的定義和功能召喚:

var express = require('express'); 
var fs = require('fs'); 
var path = require('path'); 
var app = express(); 

// Works 
var routes = require('./routes/index'); 
app.use('/', routes); 


// 404 
getRoutes('routes'); 

function getRoutes(dir, cur) { 
    if(cur === undefined) { 
     cur = '/'; 
    } 
    routes = fs.readdirSync(path.join(__dirname, dir)); 
    routes.forEach(function (file) { 

     fs.stat(dir + "/" + file, function (err, stats) { 
      if (err) { 
       console.log(err); 
      } 
      else if (stats.isFile()) { 
       var routeFilePath = "./" + path.join(dir, file); 
       var route = path.join(cur, file.replace(/\.[^/.]+$/, ""))+'/'; 
       if(file == 'index.js') { 
        route = cur; 
       } 
       console.log(route, "defined in:", routeFilePath); 

       var routeFile = require(routeFilePath); 
       app.use(route, routeFile); 
      } 
      else if (stats.isDirectory()) { 
       getRoutes(path.join(dir, file), path.join(cur, file)); 
      } 
     }); 
    }); 
} 

請注意,是的app.use()作品直接調用。 有沒有人看到錯誤?

console.log(route, "defined in:", routeFilePath);輸出:

/ defined in: ./routes/index.js 
/users/ defined in: ./routes/users.js 
/api/foo/ defined in: ./routes/api/foo.js 
/api/test/bar/ defined in: ./routes/api/test/bar.js 

看起來正確的給我。

回答

0

問題是fs.stats()是異步的。路線必須同步定義,如:

function getRoutes(dir, cur) { 
    if(cur === undefined) { 
     cur = '/'; 
    } 
    routes = fs.readdirSync(path.join(__dirname, dir)); 
    routes.forEach(function (file) { 

     var stats = fs.statSync(dir + "/" + file); 
     if (stats.isFile()) { 
      var routeFilePath = "./" + path.join(dir, file); 
      var route = path.join(cur, file.replace(/\.[^/.]+$/, ""))+'/'; 
      if(file == 'index.js') { 
       route = cur; 
      } 
      console.log(route, "defined in:", routeFilePath); 

      var routeFile = require(routeFilePath.replace(/\.[^/.]+$/, "")); 
      console.log(routeFile); 
      app.use(route, routeFile); 
     } 
     else if (stats.isDirectory()) { 
      getRoutes(path.join(dir, file), path.join(cur, file)); 
     } 

    }); 
}