2014-11-21 3 views
0

Я начал проект нового узла и хотел динамически добавлять маршруты. Я делал это раньше, но никогда больше не углублялся в глубину, чем один уровень папок. Для этой цели я придумал рекурсивную функцию для добавления маршрутов и прохождения через возможные подпапки. Функция вызывается в моем приложении. Папка проекта выглядит следующим образом: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)); 
     } 

    }); 
} 
Смежные вопросы