discord.js v14命令处理器无法读取子文件夹问题求助
Discord.js v14 无法读取命令子文件夹的问题解决
问题背景
使用discord.js v14.13.0和glob v10.3.4开发机器人时,尝试加载./commands/**/*.js路径下子文件夹中的命令,但机器人无法读取子文件夹内容,运行时报错。
原index.js代码
console.clear(); console.log("🛠 Loading..."); const fs = require('node:fs'); const path = require('node:path'); const { glob, globSync, globStream, globStreamSync, Glob } = require("glob"); const { Client, Collection, GatewayIntentBits } = require("discord.js"); const { token } = require("./config.json"); const client = new Client({ intents: [GatewayIntentBits.Guilds] }); client.commands = new Collection(); const commandsPath = path.join(__dirname, 'commands'); const commandFiles = glob.sync(path.join(commandsPath, "**/*.js")); for (const file of commandsPath) { const filePath = path.join(commandsPath, file); const command = require(filePath); if('data' in command && 'execute' in command) { client.commands.set(command.data.name, command); } else { console.log(`⛔ [WARNING] The command at ${filePath} is missing a required "data" or "execute" propety!`); } } const eventsPath = path.join(__dirname, 'events'); const eventFiles = fs.readdirSync(eventsPath).filter(file => file.endsWith('.js')); for (const file of eventFiles) { const filePath = path.join(eventsPath, file); const event = require(filePath); if (event.once) { client.once(event.name, (...args) => event.execute(...args)); } else { client.on(event.name, (...args) => event.execute(...args)); } } client.login(token);
报错信息
node:internal/validators:162 throw new ERR_INVALID_ARG_TYPE(name, 'string', value); ^ TypeError [ERR_INVALID_ARG_TYPE]: The "id" argument must be of type string. Received an instance of Array at new NodeError (node:internal/errors:405:5) at validateString (node:internal/validators:162:11) at Module.require (node:internal/modules/cjs/loader:1108:3) at require (node:internal/helpers:130:18) at Object.<anonymous> (/home/filip/Code/SimpleDCbot/index.js:28:1) at Module._compile (node:internal/modules/cjs/loader:1233:14) at Module._extensions..js (node:internal/modules/cjs/loader:1287:10) 🛠 Loading... node:internal/modules/cjs/loader:1051 throw err; ^ Error: Cannot find module '/home/filip/Code/SimpleDCbot/commands/' Require stack: - /home/filip/Code/SimpleDCbot/index.js at Module._resolveFilename (node:internal/modules/cjs/loader:1048:15) at Module._load (node:internal/modules/cjs/loader:901:27) at Module.require (node:internal/modules/cjs/loader:1115:19) at require (node:internal/helpers:130:18) at Object.<anonymous> (/home/filip/Code/SimpleDCbot/index.js:32:21) at Module._compile (node:internal/modules/cjs/loader:1233:14) at Module._extensions..js (node:internal/modules/cjs/loader:1287:10) at Module.load (node:internal/modules/cjs/loader:1091:32) at Module._load (node:internal/modules/cjs/loader:938:12) at Function.executeUserEntryPoint [as runMain] (node:internal/run_main:83:12) { code: 'MODULE_NOT_FOUND', requireStack: [ '/home/filip/Code/SimpleDCbot/index.js' ] } Node.js v20.5.1
错误原因分析
- 循环对象错误:代码中使用
for (const file of commandsPath)循环,但commandsPath是字符串类型的文件夹路径,而非glob.sync()返回的文件路径数组,导致循环遍历的是字符串的每个字符,而非目标文件。 - 路径重复拼接:即使循环对象正确,
path.join(commandsPath, file)也会重复拼接路径(因为commandFiles中的元素已经是完整的绝对路径),最终导致无效路径。
修正后的代码
只需修改命令加载的循环部分,其他代码保持不变:
console.clear(); console.log("🛠 Loading..."); const fs = require('node:fs'); const path = require('node:path'); const { glob, globSync, globStream, globStreamSync, Glob } = require("glob"); const { Client, Collection, GatewayIntentBits } = require("discord.js"); const { token } = require("./config.json"); const client = new Client({ intents: [GatewayIntentBits.Guilds] }); client.commands = new Collection(); const commandsPath = path.join(__dirname, 'commands'); const commandFiles = glob.sync(path.join(commandsPath, "**/*.js")); // 修正后的命令加载循环 for (const file of commandFiles) { const command = require(file); if('data' in command && 'execute' in command) { client.commands.set(command.data.name, command); } else { console.log(`⛔ [WARNING] The command at ${file} is missing a required "data" or "execute" property!`); } } const eventsPath = path.join(__dirname, 'events'); const eventFiles = fs.readdirSync(eventsPath).filter(file => file.endsWith('.js')); for (const file of eventFiles) { const filePath = path.join(eventsPath, file); const event = require(filePath); if (event.once) { client.once(event.name, (...args) => event.execute(...args)); } else { client.on(event.name, (...args) => event.execute(...args)); } } client.login(token);
关键修改点
- 循环对象从
commandsPath改为commandFiles,遍历glob返回的所有命令文件路径 - 直接使用
file作为require的路径,无需再次拼接commandsPath - 修正了警告信息中的拼写错误(
propety改为property)
内容的提问来源于stack exchange,提问作者Huskyki Games
相关产品推荐
相关产品推荐

