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

NodeJS如何动态导入模块?批量导入router.js方案咨询

解决方案:批量导入modules下所有router.js模块

你当前生成的import语句字符串没法直接执行,因为ES模块的import是静态语法,只能在代码解析阶段处理,没法在运行时通过执行字符串来实现导入。下面给你两种可行的方案:

方案一:使用动态导入(import())

通过import()函数可以在运行时动态加载模块,修改你的扫描代码,先收集所有router.js的路径,再批量动态导入:

import fs from "fs"
import path from "path"

// 扫描目录,返回所有router.js的相对路径
function scanDirForRouters(dirPath) {
    let routerPaths = []
    const files = fs.readdirSync(dirPath)
    for (const file of files) {
        const fullPath = path.join(dirPath, file)
        const isDirectory = fs.statSync(fullPath).isDirectory()
        
        if (isDirectory) {
            routerPaths = [...routerPaths, ...scanDirForRouters(fullPath)]
        } else if (file === "router.js") {
            // 转换为相对于当前index.js的路径
            const relativePath = path.relative(
                path.dirname(import.meta.url.replace('file://', '')),
                fullPath
            ).replace(/\\/g, '/') // 适配Windows路径格式
            routerPaths.push(relativePath)
        }
    }
    return routerPaths
}

// 批量加载所有路由模块
async function loadAllRouters() {
    const paths = scanDirForRouters(path.join(path.dirname("."), "modules"))
    // 动态导入所有模块
    const modules = await Promise.all(paths.map(p => import(`./${p}`)))
    // 提取每个模块的默认导出(根据你的router.js导出方式调整)
    return modules.map(m => m.default)
}

// 使用示例:加载完成后处理路由
loadAllRouters().then(routers => {
    // 这里可以把路由注册到框架(比如Express/Koa)
    console.log("已加载所有路由:", routers)
})

优点:无需额外构建步骤,运行时自动扫描加载;缺点:异步加载,需要处理Promise流程。

方案二:预生成静态导入文件

写一个脚本预先扫描目录,生成包含所有import语句的文件,再在index.js中直接导入这个文件。

步骤1:编写生成脚本(generate-routers.js)

import fs from "fs"
import path from "path"

function scanDirForRouters(dirPath) {
    let routers = []
    const files = fs.readdirSync(dirPath)
    for (const file of files) {
        const fullPath = path.join(dirPath, file)
        const isDirectory = fs.statSync(fullPath).isDirectory()
        
        if (isDirectory) {
            routers = [...routers, ...scanDirForRouters(fullPath)]
        } else if (file === "router.js") {
            const relativePath = path.relative(path.dirname("."), fullPath).replace(/\\/g, '/')
            // 生成唯一变量名,避免冲突
            const varName = relativePath.replace(/[\/\.]/g, "") + "Router"
            routers.push({ path: relativePath, varName })
        }
    }
    return routers
}

// 生成导入和导出语句
const routers = scanDirForRouters(path.join(path.dirname("."), "modules"))
const imports = routers.map(r => `import ${r.varName} from './${r.path}'`)
const exportStr = `export default [${routers.map(r => r.varName).join(", ")}]`

// 写入routers.js文件
fs.writeFileSync(
    path.join(path.dirname("."), "routers.js"),
    [...imports, exportStr].join("\n")
)

步骤2:运行脚本生成文件

在package.json中添加脚本:

{
  "scripts": {
    "generate:routers": "node generate-routers.js"
  }
}

执行npm run generate:routers,会自动生成routers.js文件,内容类似:

import SomeModuleRouter from './modules/SomeModule/router.js'
import SomeOtherModuleSubModuleRouter from './modules/SomeOtherModule/SubModule/router.js'
export default [SomeModuleRouter, SomeOtherModuleSubModuleRouter]

步骤3:在index.js中导入

import routers from './routers.js'

// 直接使用所有路由
console.log("已加载所有路由:", routers)

优点:同步加载,符合ES模块静态特性,构建工具可正常分析;缺点:新增/删除模块后需要重新运行生成脚本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 00:06:24