You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express中使用内联import报错:app.use()需中间件函数

TypeError: app.use() requires a middleware function(ES6内联import替换问题)

问题描述

将项目切换至ES6语法,替换所有内联require为import时,顶层import正常,但替换内联调用时出现错误:

TypeError: app.use() requires a middleware function

项目主文件代码:

// We need these modules to be present.
import path from "path";
import dotEnv from "dotenv";
import express from "express";
import { fileURLToPath } from 'url';
import connectToDatabase from "./database.js";
import morganMiddleware from "./middlewares/morgan.middleware.js";

// Initialise exress
const app = express();

// Initialise dotEnv;
dotEnv.config();

// Define file and directory path
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Load environment variables
const PORT = process.env.PORT || 1313;

// Properly parse the json and urlencoed data
app.use(express.urlencoded({ extended: false }));
app.use(express.json());

// Add the morgan middleware
app.use(morganMiddleware);

// When we respond with a json object, indent every block with 4 spaces.
app.set("json spaces", 4);

// Where should we look for the static files
app.use(express.static(path.join(__dirname, "../public")));

//Load the different routes
app.use(import("./controllers/index.js")); // 出错的行

// Connect to database
connectToDatabase();

// Custom Error handling
app.use((req, res) => {
   res.status(404).json({
      type: "error",
      message: "404: Page not Found"});
});

app.use((error, req, res, next) => {
   res.status(500).json({
      type: "error",
      message: "500: Internal Server Error"});
});

// Start the server
app.listen(PORT, () => {
   console.log(`Server is running on port ${PORT}`);
});

controllers/index.js代码:

// Loading the modules
import { Router } from "express";

const router = Router()

// Load the models
import ProjectsData, { addProject } from "../models/projects.js";

router.post("/", (req, res) => {
    res.send("Cool. We are working. Now you can proceed to cry.");
});

export default router;

原因分析

import()是ES6的动态导入语法,它的返回值是一个Promise对象,而非直接获取模块导出的内容。而app.use()要求传入的是中间件函数(或Router实例,本质属于中间件),直接将Promise传递给它,自然不符合参数要求,触发错误。

解决方案

方案1:改用顶层静态导入(推荐)

路由模块属于应用启动时必须加载的核心模块,不需要动态导入。将路由模块改为顶层静态导入,直接获取导出的Router实例:

// 在文件顶部添加静态导入
import indexRouter from "./controllers/index.js";

// ... 其他代码不变

// 替换原来的动态导入行
app.use(indexRouter);

方案2:动态导入时处理Promise(按需加载场景)

如果确实需要动态导入(比如按需加载路由的场景),需要等待Promise resolve后获取导出的Router实例,可通过async/await实现:

// 将启动逻辑封装为异步函数
async function startServer() {
  // ... 所有初始化代码(除了路由加载和启动服务)保持不变

  // 等待动态导入完成,获取默认导出的Router
  const { default: indexRouter } = await import("./controllers/index.js");
  app.use(indexRouter);

  // 错误处理和启动服务放在异步函数内
  app.use((req, res) => {
     res.status(404).json({
        type: "error",
        message: "404: Page not Found"});
  });

  app.use((error, req, res, next) => {
     res.status(500).json({
        type: "error",
        message: "500: Internal Server Error"});
  });

  app.listen(PORT, () => {
     console.log(`Server is running on port ${PORT}`);
  });
}

// 启动服务
startServer();

内容的提问来源于stack exchange,提问作者CrumpledMemories

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 17:40:34