TypeError:Router.use()需要中间件功能,但未定义

时间:2018-11-18 20:46:11

标签: node.js express router

每个人我都是NODEJS的初学者,我正在尝试制作小型聊天应用程序。我在 server.js中遇到路由问题。 [在app.use( /',chatcat.router); ] 。我已附上以下错误。谁能告诉我?如何解决此问题。预先感谢...

server.js

const express=require('express');

const app=express();

const chatcat=require('./app');

app.set('port',process.env.PORT || 8086);

app.use(express.static('public'));

app.set('view engine','ejs');

app.use('/',chatcat.router);

app.listen(app.get('port'),()=>{
    console.log('server is listening on port: ',app.get('port'));
});

app / index.js

const routes=require('./routes');

module.exports={
     router: routes() 
}

app / routes / index.js:

'use strict';

const h=require('../helpers');

console.log('routers/index outside');

module.exports=()=>{

    console.log('routers/index inside');

    let routes={

        'get':{
            '/':(req,res,next)=>{
                res.render('login');
            },
            '/chat':(req,res,next)=>{
                res.render('chatroom');
            },
            '/rooms':(req,res,next)=>{
                res.render('rooms');
            }
        } ,
        'post':{
            '/chat':(req,res,next)=>{
              res.render('chatroom');
            }
        }    
    }

    return h.route12(routes);
};

app / helpers / index.js

'use strict';

const express=require('express');

const router=express.Router();

console.log('helpers/index outside');
let _registerRoutes=(routes,method)=>{

    for(let key in routes){
        if( (typeof routes[key] === 'object') && (routes[key] !==null) && !( routes[key] instanceof Array)){

            _registerRoutes(routes[key],key);
        }
        else{
            if(method === 'get'){
                console.log('get in');
                router.get(key,routes[key]);
            } 
            else if(method ==='post'){
                console.log('post in');
                router.post(key,routes[key]);
            }
        }
    }
}

let route12=routes=>{
    console.log('calling registerroutes');
    _registerRoutes(routes);
}

module.exports={
    route12
}

我遇到了类似这样的错误:

E:\ STUDIES \ Node Technologies \ NodeJS \ chatcat \ node_modules \ express \ lib \ router \ index.js:458       抛出新的TypeError('Router.use()需要中间件功能,但是得到了'+ gettype(fn))       ^

TypeError:Router.use()需要中间件功能,但未定义     在Function.use(E:\ STUDIES \ Node Technologies \ All关于NodeJS \ chatcat \ node_modules \ express \ lib \ router \ index.js:458:13)     在功能。 (E:\ STUDIES \ Node Technologies \ All关于NodeJS \ chatcat \ node_modules \ express \ lib \ application.js:220:21)     在Array.forEach()     在Function.use(E:\ STUDIES \ Node Technologies \ All关于NodeJS \ chatcat \ node_modules \ express \ lib \ application.js:217:7)     在对象。 (E:\ STUDIES \ Node Technologies \ All关于NodeJS \ chatcat \ server.js:13:5)     在Module._compile(module.js:653:30)     在Object.Module._extensions..js(module.js:664:10)     在Module.load(module.js:566:32)     在tryModuleLoad(module.js:506:12)     在Function.Module._load(module.js:498:3)

2 个答案:

答案 0 :(得分:1)

让我们一步一步地往回走:

在这一行:

app.use('/',chatcat.router);

当您认为chatcat.router是一个函数时,您得到一个错误,提示它未定义。变量chatcat来自此:

const chatcat=require('./app');

因此,在app / index.js中,您有以下内容:

const routes=require('./routes');

module.exports={
     router: routes() 
}

因此,这意味着您正在调用应该返回require('./routes');的函数,并将其返回值放入导出中。

当我们进入app/routes/index.js时,我们看到您正在导出一个函数,该函数在被调用时将返回以下内容:

return h.route12(routes);

h来自哪里:

const h=require('../helpers');

当我们查看app/helpers/index.js时,我们看到它正在导出route12函数:

let route12=routes=>{
    console.log('calling registerroutes');
    _registerRoutes(routes);
}

module.exports={
    route12
}

而且,您看到route12()在被调用时不会返回任何内容。

因此,您最终得到undefined


因此,快速而肮脏的解决方法是使route12()返回一个函数,该函数与您想要的中间件函数一样。

但是,说实话,这段代码很混乱。看一下找出chatcat.router实际应该做的工作量。应该不难。您已经在顶级导入和实际实现之间放置了一堆中间文件,所有这些层都没有增加任何价值。他们所做的只是模糊的事情。而且,由于这是一个中间件功能,所以您可能不会在其他许多地方使用相同的中间件功能。

有很多方法可以清除此问题,但是我建议将中间件功能放在其自己的模块中,然后直接require()放入其中。如果中间件功能需要访问其他功能,则根据需要使用require()。模块化通常应尽可能浅。您不必遵循一连串的必需模块,而这些模块不会为实际实现增加任何价值。


这里似乎还存在一个概念上的问题。 app.use()应该用于安装中间件(参与处理传入请求的请求处理程序)。但是,您的route12()不仅不会返回任何可用作中间件的东西,甚至看起来都不像是生活的目的。当我们查看_registerRoutes()时,您似乎正在尝试重新实现Express已提供的功能,但它似乎是错误的实现,因为您假设它已传递了第二个参数method您自己的代码不会传递给它,然后在其中的代码尝试将内容放到从未挂接到您应用程序的router上。

总体而言,可能有更简单的方法来执行您要尝试执行的操作。在这里并没有真正描述您要完成的工作,而且该实现还不够基础,我无法完全说出您打算做什么,以了解如何建议简化。

无论如何,我已经向您解释了为什么您遇到了原始错误。希望您可以从那里获取并修复/简化。

答案 1 :(得分:0)

@ jfriend00 谢谢您宝贵的时间来解决我的错误。根据您的建议,我已解决了该错误...请参阅下面的代码,我在

中所做的更改

app / helpers / index.js:

'use strict';

const express=require('express');

const router=express.Router();

console.log('helpers/index outside');
let _registerRoutes=(routes,method)=>{
    
    for(let key in routes){
        if( (typeof routes[key] === 'object') && (routes[key] !==null) && !( routes[key] instanceof Array)){
            
            _registerRoutes(routes[key],key);
        }
        else{
            if(method === 'get'){
                console.log('get in');
                router.get(key,routes[key]);
            } 
            else if(method ==='post'){
                console.log('post in');
                router.post(key,routes[key]);
            }
        }
    }
    return router;
}


let route12=routes=>{
    console.log('calling registerroutes');
    let x= _registerRoutes(routes);
    return x;
}

module.exports={
    route12
}

您提到了为什么要编写这样的代码这是不可靠和可扩展的。是的,您所说的是对的。只是我尝试了不同的方法。大多数时候,我想遵循 Router class strong>挂载不同的API。谢谢您的建议。我附上了最新的代码,这样可以吗?我可以这样吗? 纠正我,如果我错了。

app/index.js


'use strict';

const express=require('express');

const router=express.Router();

router.get('/',(req,res)=>{
    res.render('login');
});

router.get('/chat',(req,res)=>{
    res.render('chatroom');
});

router.get('/rooms',(req,res)=>{
    res.render('rooms');
});

router.get('/info',(req,res)=>{
    res.send("<h1> Information Page </h1>");
});

module.exports={

    router:router
};
server.js

const express=require('express');

const app=express();

const chatcat=require('./app');

app.set('port',process.env.PORT || 8086);

app.use(express.static('public'));

app.set('view engine','ejs');

app.use('/',chatcat.router);

app.listen(app.get('port'),()=>{
    console.log('server is listening on port: ',app.get('port'));
});