使用ESM时在discord.js中遭遇命令/事件处理器路径问题
Discord.js ESM环境下命令/事件处理器修复方案
核心问题分析
- 路径拼接错误:误用
path.dirname()拼接路径,该方法仅用于获取父目录路径,正确拼接应使用path.join()。 - ESM导入路径格式错误:ESM的
import()不支持直接传入本地文件路径字符串,必须转换为file://开头的URL格式,否则会触发ERR_UNSUPPORTED_ESM_URL_SCHEME错误。
修改后的index.js代码
import { Client, GatewayIntentBits, Collection } from 'discord.js'; import 'dotenv/config'; import fs from 'fs'; import path from 'path'; import url from 'url'; const client = new Client({ intents: [GatewayIntentBits.Guilds], }); client.commands = new Collection(); const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); // 正确拼接commands目录路径 const commandsPath = path.join(__dirname, 'commands'); const commandFiles = fs .readdirSync(commandsPath) .filter((file) => file.endsWith('.js')); for (const file of commandFiles) { // 拼接单个命令文件的完整路径 const filePath = path.join(commandsPath, file); // 将本地路径转换为ESM支持的URL格式 const commandModule = await import(url.pathToFileURL(filePath).href); client.commands.set(commandModule.default.data.name, commandModule.default); } client.on('ready', () => { console.log(`${client.user.tag} has logged in!`); }); client.login(process.env.TOKEN);
修改后的deployCommand.js代码
import { REST } from '@discordjs/rest'; import { Routes } from 'discord.js'; import 'dotenv/config'; import fs from 'fs'; import path from 'path'; import url from 'url'; const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); const commands = []; // 正确拼接commands目录路径 const commandsPath = path.join(__dirname, 'commands'); const commandFiles = fs .readdirSync(commandsPath) .filter((file) => file.endsWith('.js')); for (const file of commandFiles) { // 拼接单个命令文件的完整路径 const filePath = path.join(commandsPath, file); // 将本地路径转换为ESM支持的URL格式 const commandModule = await import(url.pathToFileURL(filePath).href); commands.push(commandModule.default.data.toJSON()); } const rest = new REST({ version: '10' }).setToken(process.env.TOKEN); rest .put( Routes.applicationGuildCommands( process.env.CLIENT_ID, process.env.GUILD_ID ), { body: commands } ) .then(() => console.log('Successfully registered application commands.')) .catch(console.error);
关键修改说明
- 替换
path.dirname()为path.join():正确拼接目录与文件路径,避免路径结构错误。 - 使用
url.pathToFileURL(filePath).href:将本地文件路径转换为ESM导入所需的file://格式URL,解决ERR_UNSUPPORTED_ESM_URL_SCHEME错误。 - 调整导入语句的变量接收:确保正确获取命令模块的
default导出(ESM模块默认导出需要显式获取)。
内容的提问来源于stack exchange,提问作者Desmond Nutes
相关产品推荐
相关产品推荐

