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

Discord.js旧代码转ES6遇动态导入问题求助

Discord机器人ES6动态加载命令问题解决

问题场景

我正在将Discord机器人的旧CommonJS代码转换为ES6语法,原代码如下:

const commandFiles = fs.readdirSync('./commandsBackend/').filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
  const command = require(`./commandsBackend/${file}`);
  client.commands.set(command.name, command);
}

if (interaction.commandName === 'ping' || interaction.commandName === 'p') {
  client.commands.get('ping').execute(message, args, db);
};

转换const command = require(./commandsBackend/${file});这行时,尝试使用import command from ./commandsBackend/${file}或`import {command} from `./commandsBackend/${file}均失败,报错信息:

file:///home/runner/VeriusBot/index.js:33
  import command from `./commandsBackend/${file}`;
         ^^^^^^^

SyntaxError: Unexpected identifier

需要实现无需在文件顶部逐个导入所有命令的动态加载功能。

解决方案

ES6的静态import语句不支持在循环中使用模板字符串动态生成路径,必须使用动态导入函数import(),它返回Promise,因此需要异步处理逻辑。

修改后代码示例

// 首先确保package.json中添加"type": "module",让Node.js识别ES6模块
import fs from 'fs';
import path from 'path';

// 封装异步加载命令的函数
async function loadCommands(client) {
  const commandDir = './commandsBackend/';
  const commandFiles = fs.readdirSync(commandDir).filter(file => file.endsWith('.js'));

  for (const file of commandFiles) {
    const filePath = path.join(commandDir, file);
    // 动态导入需用await解析Promise
    const commandModule = await import(filePath);
    // 根据命令文件的导出方式获取命令对象:默认导出取default,命名导出取对应字段
    const command = commandModule.default || commandModule.command;
    client.commands.set(command.name, command);
  }
}

// 在机器人就绪事件中调用加载函数
client.on('ready', async () => {
  await loadCommands(client);
  console.log('所有命令加载完成');
});

// 交互处理逻辑(注意参数可能需调整为interaction而非message,适配Discord.js v14+)
if (interaction.commandName === 'ping' || interaction.commandName === 'p') {
  client.commands.get('ping').execute(interaction, args, db);
};

关键注意事项

  • 启用ES6模块:在项目根目录的package.json中添加"type": "module",否则Node.js会以CommonJS模式解析文件,导致import语法报错。
  • 路径处理:使用path.join拼接文件路径,避免Windows和Linux系统的路径分隔符差异问题。
  • 导出匹配:确认命令文件的导出方式:
    • 若命令文件用默认导出:export default { name: 'ping', execute: () => {} },则取commandModule.default
    • 若用命名导出:export const command = { name: 'ping', execute: () => {} },则取commandModule.command

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 00:10:51