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

Node.js启用ES模块后,如何替换require实现Express路由动态导入?

动态导入ES模块实现Express路由自动映射

已经通过在package.json中添加"type": "module"将Node.js项目转为ES模块,原有的路由自动注册代码使用require()实现:

readdirSync("./routes").map((route) => app.use("/api", require(`./routes/${route}`)));

但路由文件已改为ES模块语法导出(如./routes/auth.js):

import express from "express";

const router = express.Router();

router.post("/register", (req, res) => {
    console.log("register endpoint -> ", req.body);
});

export default router;

由于ES模块的import...from是静态导入,必须在编译时确定路径,无法适配运行时动态生成的路由路径,因此需改用动态import()函数实现,同时处理异步逻辑,修改后的代码如下:

import { readdirSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
import express from 'express';

const app = express();

// ES模块中模拟__dirname(原生无该变量)
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const routesDirectory = join(__dirname, 'routes');

// 异步加载并注册所有路由
async function registerRoutes() {
  // 过滤出routes目录下的.js文件,避免导入非路由文件
  const routeFiles = readdirSync(routesDirectory).filter(file => file.endsWith('.js'));

  // 并行处理所有路由导入,提升效率
  await Promise.all(routeFiles.map(async (file) => {
    // 动态导入路由模块,解构获取default导出的router
    const { default: router } = await import(`./routes/${file}`);
    app.use('/api', router);
  }));
}

// 确保路由全部注册完成后再启动服务器
registerRoutes().then(() => {
  app.listen(3000, () => {
    console.log('服务器运行在3000端口');
  });
}).catch(err => {
  console.error('路由加载失败:', err);
});

关键说明:

  • 动态import()是ES模块提供的运行时导入方式,返回Promise,需配合async/await处理异步逻辑
  • ES模块中无__dirname,通过import.meta.url结合fileURLToPath、dirname获取当前文件目录,避免相对路径错误
  • 用Promise.all并行导入所有路由,比逐个串行导入更高效
  • 添加文件过滤逻辑,只处理.js后缀的路由文件,防止导入无关文件报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 07:23:28