Express启动报app.use() requires a middleware function错误排查
Express 运行抛出
app.use() requires a middleware function 错误排查 问题场景
在Node.js环境使用Express框架开发注册、登录页面,运行app.js时抛出上述错误。
问题根因(按触发优先级排序)
- Cookie解析中间件写法错误
代码中写的是:
app.use("cookieParser()");app.use()接收的参数必须是中间件函数,这里传入的是普通字符串,完全没有调用提前引入的cookieParser模块,是直接触发本次报错的核心原因。- Cookie解析中间件写法错误
- 中间件、路由注册顺序完全错误
Express中间件严格按照代码注册的顺序执行,当前代码把路由挂载、404处理、错误处理都写在了express.json()、express.urlencoded()、express.static()、session等基础中间件之前,会导致路由逻辑拿不到请求体、session、静态资源等数据,同时错误处理中间件提前注册无法捕获后续逻辑的报错。
- 中间件、路由注册顺序完全错误
- 未引入
createError依赖
404处理逻辑中调用了createError(404),但代码中没有安装/引入http-errors包,运行时会触发createError is not defined错误。
- 未引入
- dotenv配置未生效
代码中写的是require("dotenv").config;,没有加括号执行config方法,环境变量无法正常加载。
- dotenv配置未生效
- 全局变量污染
根路由逻辑中直接写session= req.session;,覆盖了顶部引入的express-session模块变量,会导致后续session逻辑异常。
- 全局变量污染
- 冗余无效引入
代码中const e = require("express");属于重复引入且未使用的冗余代码。
- 冗余无效引入
- 路由部分潜在问题
首先路由引入路径写法不规范:当前app.js在src目录下,routes目录是src的子目录,引入路径应该写./routes/xxx而不是../src/routes/xxx,虽然后者路径解析后可能指向同一个文件,但容易出现路径解析错误。
其次需要确认四个路由文件(regis.js/login.js/dashboard.js/logout.js)中都正确导出了Router实例,即每个文件末尾必须有module.exports = router;,如果没有导出,引入的变量值为undefined,传入app.use()也会触发本次的报错。
- 路由部分潜在问题
修正后的完整app.js代码
const express= require("express"); const app= express(); const path= require("path"); const hbs= require("hbs"); const session= require("express-session"); const createError = require('http-errors'); // 需先执行 npm i http-errors 安装依赖 const port= process.env.PORT || 3000; require("dotenv").config(); // 补括号执行config方法 const static_path= path.join(__dirname,"../public"); const template_path= path.join(__dirname,"../templates/views"); const partials_path= path.join(__dirname,"../templates/partials"); const db= require("./db/db.js"); const cookieParser= require("cookie-parser"); hbs.registerPartials(partials_path); // 修正路由引入路径 var regisRouter= require("./routes/regis"); var loginRouter= require("./routes/login"); var dashbRouter= require("./routes/dashboard"); var logoutRouter= require("./routes/logout"); // 先注册基础核心中间件 app.use(express.static(static_path)); app.use(express.json()); app.use(express.urlencoded({extended:false})); app.use(cookieParser()); // 去掉引号,正确调用中间件函数 app.set("view engine", "hbs"); app.set("views",template_path); const oneDay = 1000 * 60 * 60 * 24; app.use(session({ secret: "secret123", resave: false, saveUninitialized: true, cookie: {maxAge: oneDay} })); // 基础中间件注册完成后再挂载路由 app.use('/regis',regisRouter); app.use('/login',loginRouter); app.use('/dashboard',dashbRouter); app.use('/logout',logoutRouter); app.get("/",(req,res) =>{ // 不要覆盖全局session变量,单独声明变量存储请求session const userSession = req.session; if(userSession.id) { res.send("Welcome User <a href='/logout'>click to logout</a>"); } else res.render("index"); }); // 所有路由注册完成后再挂载404处理 app.use(function(req, res, next) { next(createError(404)); }); // 错误处理中间件放在最末尾注册 app.use(function(err, req, res, next) { res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; res.status(err.status || 500); res.render('error'); }); app.listen(port,() =>{ console.log(`this is port no. ${port}`); });
额外检查项
如果修正上述代码后仍报错,打开四个路由文件,确认每个文件都符合Router写法规范,以regis.js为例:
const express = require('express'); const router = express.Router(); // 路由逻辑写在这里,比如 router.get('/', (req,res) => { res.send('register page') }) module.exports = router; // 必须有这行导出,否则引入值为undefined,会触发中间件类型报错
项目目录参考

内容的提问来源于stack exchange,提问作者Tushar Singh
相关产品推荐
相关产品推荐

