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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 16:34:59