Guide discord.js
Fonctionnalités supplémentaires

Rechargement des Commandes

Lors de l'écriture de vos commandes, vous pourriez trouver fastidieux de redémarrer votre bot à chaque fois pour tester les plus petits changements. Avec un gestionnaire de commande, vous pouvez éliminer ce problème et recharger vos commandes pendant que votre bot est en cours d'exécution.

ESM ne supporte pas require et l'effacement du cache d'importation. Vous pouvez utiliser hot-esm pour importer des fichiers sans cache. Le support de Windows est expérimental selon ce problème.

Cette section suppose que vous avez suivi la partie Gestion des commandes du guide.

commands/utility/reload.js
const { SlashCommandBuilder } = require('discord.js');

module.exports = {
	data: new SlashCommandBuilder()
		.setName('reload')
		.setDescription('Reloads a command.')
		.addStringOption((option) => option.setName('command').setDescription('The command to reload.').setRequired(true)),
	async execute(interaction) {
		// ...
	},
};

D'abord, vous devez vérifier si la commande que vous voulez recharger existe. Vous pouvez faire cette vérification de manière similaire à l'obtention d'une commande.

module.exports = {
	// ...
	async execute(interaction) {
		// ...
		const commandName = interaction.options.getString('command', true).toLowerCase();
		const command = interaction.client.commands.get(commandName);

		if (!command) {
			return interaction.reply(`There is no command with name \`${commandName}\`!`);
		}
	},
};

La commande de rechargement ne devrait idéalement pas être utilisée par tous les utilisateurs. Vous devriez la déployer comme une commande de guilde dans une guilde privée.

Pour construire le chemin de fichier correct, vous aurez besoin du nom du fichier. Vous pouvez utiliser command.data.name pour ce faire.

En théorie, tout ce qu'il faut faire est de supprimer la commande précédente de client.commands et de relancer require sur le fichier. En pratique, vous ne pouvez pas le faire facilement car require() met en cache le fichier. Si vous le relancier, vous chargeriez le fichier précédemment mis en cache sans aucun changement. Vous devez d'abord supprimer le fichier de require.cache, puis seulement relancer require et définir le fichier de commande sur client.commands :

delete require.cache[require.resolve(`./${command.data.name}.js`)];

try {
	const newCommand = require(`./${command.data.name}.js`);
	interaction.client.commands.set(newCommand.data.name, newCommand);
	await interaction.reply(`Command \`${newCommand.data.name}\` was reloaded!`);
} catch (error) {
	console.error(error);
	await interaction.reply(
		`There was an error while reloading a command \`${command.data.name}\`:\n\`${error.message}\``,
	);
}

L'extrait ci-dessus utilise un bloc try...catch pour charger le fichier de commande et l'ajouter à client.commands. En cas d'erreur, il enregistrera l'erreur complète dans la console et notifiera l'utilisateur avec le composant de message d'erreur error.message. Notez que vous ne supprimez jamais réellement la commande de la Collection de commandes et que vous la remplacez plutôt. Ce comportement vous empêche de supprimer une commande et de vous retrouver sans aucune commande après un appel require() échoué, car chaque utilisation de la commande de rechargement vérifie à nouveau cette Collection.