Comment récupérer des données utilisateurs en ligne de commande en Node.js

Un exemple de comment demander aux utilisateurs de saisir des données à partir d'un script de ligne de commande. Une traduction de l'article How do I prompt users for input from a command-line script?

Classée dans Ligne de commande

Traduction

Vous disposez donc d'un petit outil d'interface en ligne de commande (CLI), mais vous voulez pouvoir demander à l'utilisateur des données supplémentaires après le démarrage du script, plutôt que de les transmettre en tant qu'argument de ligne de commande ou de les placer dans un fichier. Pour ce faire, vous devrez écouter l'entré standard (STDIN), c'est-à-dire le clavier, que Node.js expose pour vous via process.stdin en un flux de lecture.

Les flux sont la façon dont Node.js traite les entrées/sorties ou E/S (I/O) événementielles ; c'est un sujet important, et vous pouvez en lire plus ici (EN). Pour l'instant, nous allons utiliser le module intégré readline qui est une enveloppe autour de l'E/S standard, adapté à la prise en charge des entrées utilisateur à partir de la ligne de commande (terminal).

Voici un exemple simple. Essayez ce qui suit dans un nouveau fichier :

const readline = require("readline");
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

rl.question("Quel est votre nom ? ", function(name) {
    rl.question("Où vivez vous ? ", function(country) {
        console.log(`${name}, est un citoyen de ${country}`);
        rl.close();
    });
});

rl.on("close", function() {
    console.log("\nAu revoir !");
    process.exit(0);
});

Dans le code ci-dessus, readline.createInterface() est utilisé pour créer une instance de readline en configurant les flux de lecture et d'écriture. La propriété input prend un flux de lecture comme process.stdin ou fs.createReadStream('file.txt') et la propriété output prend un flux d'écriture comme process.stdout ou process.stderr.

La méthode rl.question() affiche la requête en l'écrivant sur la sortie, attend que l'utilisateur fournisse une réponse en entrée, puis invoque la fonction de rappel (callback function) en passant l'entrée fournie comme premier argument.

Conseil : N'oubliez pas d'utiliser rl.close() pour fermer la transmission, sinon le processus restera à l'état d'inactivité idle.

La dernière partie du code utilise la méthode rl.on() pour ajouter un écouteur d'événement à l'événement de fermeture, ce qui permet simplement de mettre console.log dans le flux de sortie et de quitter le processus. Cette partie est complètement facultative et peut être supprimée à volonté. Pour plus de détails et d'utilisation, consultez la documentation ici (EN).

Si tout cela vous semble compliqué, ou si vous voulez une interface de plus haut niveau pour ce genre de choses, ne vous inquiétez pas ; comme d'habitude, la communauté Node.js est venue à la rescousse. Un module particulièrement convivial à utiliser pour cela est module Prompt, disponible sur npm :

npm install prompt

Prompt est conçu pour être facile ; si vous avez commencé à avoir les yeux vitreux dès que vous avez vu Readable Stream, alors cette section est faite pour vous. Comparez ce qui suit avec l'exemple ci-dessus :

const prompt = require('prompt');

prompt.start();

prompt.get(['username', 'email'], function (err, result) {
    if (err) { return onErr(err); }
    console.log('Entrée reçu à la ligne de commande :');
    console.log('  Username: ' + result.username);
    console.log('  Email: ' + result.email);
});

function onErr(err) {
    console.log(err);
    return 1;
}

Conseil : Ce court script démontre également la gestion correcte des erreurs dans Node ; les erreurs sont le premier argument de la fonction de rappel, et return est utilisé avec le gestionnaire d'erreurs afin que le reste de la fonction ne s'exécute pas lorsque des erreurs se produisent.

Prompt rend également trivial le traitement d'un certain ensemble de propriétés récurrentes que l'on pourrait vouloir attacher.

const prompt = require('prompt');

const properties = [
    {
        name: 'username',
        validator: /^[a-zA-Z\s\-]+$/,
        warning: 'Un Username ne doit posséder que des lettres, espace ou tiret'
    },
    {
        name: 'password',
        hidden: true
    }
];

prompt.start();

prompt.get(properties, function (err, result) {
    if (err) { return onErr(err); }
    console.log('Entrée reçu à la ligne de commande :');
    console.log('  Username: ' + result.username);
    console.log('  Password: ' + result.password);
});

function onErr(err) {
    console.log(err);
    return 1;
}

Pour plus d'informations sur Prompt, veuillez consulter la page GitHub du projet.

Lire dans une autre langue