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
相关产品推荐
相关产品推荐

