NodeJS Express 递归路由失败 (404)

nodejs express recursive routing fails (404)

本文关键字:失败 路由 Express 递归 NodeJS      更新时间:2023-09-26

我启动了一个新的节点项目,并希望动态添加路由。我以前做过,但从未比一级文件夹更深入。为此,我想出了一个递归函数来添加路由并遍历可能的子文件夹。该函数在我的应用程序中调用.js。项目文件夹如下所示:

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

对我来说看起来是正确的。

问题是 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));
        }
    });
}