Node.js中动态import与常规import行为不一致,如何批量加载路由?
如何使用import()语法实现批量路由文件导入?
我在../../src/routes/index.js中有以下代码:
import Router from '../../my_modules/nexus/Router.js' Router.get('/', function (request, response) { response.send('welcome home') }) Router.get('/about', function (request, response) { response.send('about me') })
我需要构建自定义路由API,尝试用Node.js导入该文件,运行代码如下:
import express from 'express' import Router from './Router.js' const app = express() // 静态导入可正常工作 // import '../../src/routes/index.js' // 动态导入无法正常工作 import('../../src/routes/index.js') console.log(Router.routes) // 动态导入时此处为空 app.listen(3000, function () { console.log(`App listening on http://localhost:3000`) })
静态导入时能正常获取Router.routes,但动态导入时该属性为空。由于需要批量导入routes目录下的多个文件,必须让动态导入生效,请问该如何解决?
核心原因
动态导入import()是异步操作,返回一个Promise对象,代码会继续向下执行,所以你调用console.log(Router.routes)时,路由文件还没加载完成,自然获取不到数据。而静态导入是同步加载,在代码执行前就完成了文件加载和路由注册。
解决方法
1. 单个文件动态导入:用async/await等待加载完成
将代码放在async函数中,等待动态导入完成后再访问Router.routes:
import express from 'express' import Router from './Router.js' const app = express() // 用自执行async函数包裹 (async () => { // 等待动态导入完成 await import('../../src/routes/index.js') console.log(Router.routes) // 此时已能获取到路由 })() app.listen(3000, function () { console.log(`App listening on http://localhost:3000`) })
2. 批量导入目录下所有路由文件
如果要批量导入routes目录下的多个文件,可以结合Node.js的fs模块读取目录,然后批量执行动态导入,等待所有文件加载完成:
import express from 'express' import Router from './Router.js' import fs from 'fs/promises' import path from 'path' const app = express() (async () => { // 获取routes目录的绝对路径 const routesDir = path.resolve('../../src/routes') // 读取目录下所有文件 const files = await fs.readdir(routesDir) // 筛选出.js文件,批量动态导入 await Promise.all( files .filter(file => file.endsWith('.js')) .map(file => import(path.join(routesDir, file))) ) console.log(Router.routes) // 所有路由已注册完成 })() app.listen(3000, function () { console.log(`App listening on http://localhost:3000`) })
注意事项
- 确保你的Node.js版本支持ES模块(需要在
package.json中添加"type": "module") - 如果路由文件有依赖顺序,需要自行处理加载顺序,或者在路由文件内部处理依赖
内容的提问来源于stack exchange,提问作者kjoedion
相关产品推荐
相关产品推荐

