Command Handler with Sub-Categorized folders

2019-08-19 05:30发布

问题:

This is the command handler I'm currently using, and it works as it's supposed to.

try {
  let ops = {
    active: active
  }

  let commandFile = require(`./commands/${cmd}.js`)
  commandFile.run(client, message, args, ops);
} catch (e) {
  console.log(e);
}

But as you can see, it just reads into the commands folder and pulls the .js files from there.
What I'm looking to do, is to have the commands be sub-categorized for my own "OCD" purposes, so that I can keep track of them better on my end.
Is there any way with this command handler to do so?

Also, I've already tried discord.js-commando and I don't personally like the command structure it uses.

回答1:

I would use the require-all package.

Let's assume that you have a file structure like the following:

commands:
  folder1:
    file1.js
  folder2:
    subfolder:
      file2.js

You can use require-all to require all those files altogether:

const required = require('require-all')({
  dirname: __dirname + '/commands', // Path to the 'commands' directory
  filter: /(.+)\.js$/, // RegExp that matches the file names
  excludeDirs: /^\.(git|svn)|samples$/, // Directories to exclude
  recursive: true // Allow for recursive (subfolders) research
});

The above required variable will look like this:

// /*export*/ represents the exported object from the module
{
  folder1: { file1: /*export*/ },
  folder2: { 
    subfolder: { file2: /*export*/ } 
  }
}

In order to get all the commands you need to scan that object with a recursive function:

const commands = {};

(function searchIn(obj = {}) {
  for (let key in obj) {
    const potentialCommand = obj[key];

    // If it's a command save it in the commands object
    if (potentialCommand.run) commands[key] = potentialCommand;
    // If it's a directory, search recursively in that too
    else searchIn(potentialCommand);
  }
})(required);

When you want to execute the command, simply call:

commands['command-name'].run(client, message, args, ops)

You can find a working demo (with strings) at this repl.