如何用ES6 import自动导入分散的Express路由并解决顶层导入报错?
解决ES6动态导入路由的"import只能在顶层"报错并实现自动挂载路由
你遇到的这个报错是因为静态import语句只能出现在模块的顶层作用域,而你在map的回调函数里使用了import(file),这属于块级作用域内的静态导入,不符合ES模块的规则。不过我们可以用ES6的动态import()函数来实现动态加载,同时满足你自动导入所有路由、每个路由直接挂载到API根路径的需求。
下面是具体的修改方案:
1. 修正index.js的动态导入逻辑
动态import()会返回一个Promise,我们需要等待所有路由文件加载完成后,再执行它们的挂载函数。同时要调整glob的匹配路径,确保能正确找到你的路由文件:
import express from 'express'; import mongoose from 'mongoose'; import glob from 'glob'; const app = express(); const config = { app_port: 8080 }; // 测试根路由 app.get('/', (req, res) => { res.send('Voila!!'); }); // 动态加载所有路由文件 (async () => { // 调整glob路径匹配你的实际文件结构,这里匹配modules下所有.server.routes.js文件 const files = glob.sync('modules/**/*.server.routes.js'); // 等待所有文件导入完成 const routeModules = await Promise.all( files.map(file => import(`./${file}`)) // 注意相对路径,根据项目结构调整 ); // 遍历每个路由模块,调用导出的挂载函数 routeModules.forEach(module => { // 每个路由文件导出的是默认函数,接收app实例 module.default(app); }); // 路由加载完成后再启动服务器 app.listen(config.app_port, () => { console.log(`Server running on port ${config.app_port}`); }); })();
2. 修正路由文件的路由定义
你原来的app.route用法有误——app.route()只接收路径参数,返回一个路由对象,不能直接传入回调函数。我们改成正确的路由定义方式,确保路由能直接挂载到API根路径:
// modules/users/users.server.routes.js export default (app) => { // 直接在/api路径下定义GET请求,也可根据需求用app.post/app.use等 app.get('/api', (req, res) => { res.send('User routes working'); }); // 可添加更多该模块的路由,比如: // app.get('/api/users', (req, res) => { /* 获取用户列表逻辑 */ }); };
关键说明
- 动态
import():这是ES6标准支持的动态加载模块方式,返回Promise,所以用Promise.all批量加载所有路由文件,确保所有路由挂载完成后再启动服务器。 - 路由挂载时机:把
app.listen放在异步函数内部,避免请求进来时路由还未挂载的问题。 - 路径匹配:glob的匹配规则要根据你的实际项目结构调整,比如路由文件在
app/modules下,就把路径改成app/modules/**/*.server.routes.js,确保能找到所有目标文件。
这样修改后,就能实现服务器启动时自动导入所有路由,每个路由模块直接在API根路径下定义自己的路由,同时解决了import只能在顶层的报错问题。
内容的提问来源于stack exchange,提问作者Sankarshan Katti
相关产品推荐
相关产品推荐

