Menu

readline Node.js : lire une saisie utilisateur au terminal

Node.js n'a pas de fonction prompt(). Pour poser une question à l'utilisateur dans le terminal, créez une interface readline sur process.stdin et appelez question(), ou attendez-la avec await via readline/promises.

Cette page contient des éditeurs exécutables. Modifiez, exécutez et voyez la sortie instantanément.

Pour lire une saisie utilisateur en Node.js, créez une interface readline sur process.stdin et posez la question avec rl.question(). Node.js n'a pas de prompt() : la version du navigateur ouvre une boîte de dialogue, et un programme en terminal n'en a pas. La forme moderne utilise readline/promises, où await rl.question('Name? ') renvoie la ligne tapée par l'utilisateur. Fermez l'interface quand vous avez fini, sinon le programme continue d'attendre une saisie.

question() a affiché son invite, attendu une ligne de saisie et l'a renvoyée sans le saut de ligne, donc le programme a affiché Next year you will be 37. Pour plusieurs questions, attendez un question() après l'autre avec await.

question() de readline avec un callback

L'API d'origine, présente dans toutes les versions de Node.js, passe la réponse à un callback. Des questions imbriquées donnent des callbacks imbriqués :

Le programme a affiché l'invite, puis You picked blue. La réponse est une simple chaîne, donc appliquez trim avant de comparer : sinon, un utilisateur qui tape une espace après le mot obtient 'blue ', qui n'est pas égal à 'blue'.

Lire la saisie ligne par ligne

Pour traiter chaque ligne jusqu'à la fin de l'entrée, parcourez l'interface avec for await. C'est ainsi qu'un programme lit une liste tapée par l'utilisateur (terminée par Ctrl+D) ou un fichier redirigé avec node index.js < numbers.txt. Le code plus ancien fait la même chose avec des événements, rl.on('line', fn) pour chaque ligne et rl.on('close', fn) à la fin ; la boucle, c'est cette paire d'événements écrite de haut en bas :

Le programme a affiché 3 numbers, total 49, et la boucle s'est terminée toute seule à la fin de l'entrée, donc aucun close() n'est nécessaire. Ajoutez une quatrième ligne d'entrée, 1, et le résultat devient 4 numbers, total 50.

Lire tout stdin d'un coup

Pour une entrée reçue en pipe depuis un autre programme (cat data.txt | node index.js), tout lire en un seul appel est plus simple. Le descripteur de fichier 0 est l'entrée standard. Un fichier enregistré sous Windows peut terminer ses lignes par \r\n, donc découpez sur /\r?\n/ quand l'entrée peut venir de là :

Le programme a affiché les trois articles en colonne. readFileSync(0) bloque jusqu'à ce que l'entrée soit complète, ce qui convient à un script qui lit un pipe et aux tests, mais pas à un outil interactif, où l'utilisateur taperait tout avant de voir la moindre invite.

Laquelle utiliser

Les quatre lisent la même entrée standard. Elles diffèrent par le moment où votre code reçoit le texte : une réponse à la fois, une ligne à la fois, ou tout à la fin.

BesoinUtilisez
Poser quelques questions dans l'ordrereadline/promises avec await rl.question()
Prendre en charge les versions de Node.js antérieures à 17readline avec un callback question()
Traiter chaque ligne dès qu'elle arrivefor await (const line of rl)
Lire tout un pipe ou un fichier depuis stdinfs.readFileSync(0, 'utf8')
Des valeurs connues avant le démarrage du programmeprocess.argv à la place

Erreurs fréquentes

Oublier rl.close(). L'interface garde l'entrée standard ouverte, donc le programme ne se termine jamais après la dernière question. Fermez-la une fois toutes les réponses obtenues.

Utiliser la réponse comme un nombre. Comme tout ce qui est tapé dans un terminal, la réponse est une chaîne. '36' + 1 vaut '361' ; convertissez d'abord avec Number().

Envoyer plusieurs réponses en pipe à plusieurs questions. Quand l'entrée vient d'un pipe et non d'un clavier, readline lit tout d'un coup, et une ligne qui arrive avant que sa question() soit posée est perdue. Pour une entrée en pipe, utilisez la boucle for await ou readFileSync(0).

Omettre l'option output. Sans output: process.stdout, question() n'affiche jamais son invite, et l'utilisateur fixe un terminal vide. La boucle ligne par ligne n'en a pas besoin, car elle n'affiche rien.

Questions fréquentes

Pourquoi prompt n'est-il pas défini en Node.js ?

prompt() est une fonction du navigateur qui ouvre une boîte de dialogue, et Node.js n'a pas de fenêtre où l'ouvrir. Utilisez readline en Node.js, ou un package comme prompts ou inquirer pour les menus et les champs de mot de passe.

Comment lire un mot de passe sans l'afficher ?

readline affiche chaque touche. Des packages comme prompts ou @inquirer/password masquent la saisie ; le faire vous-même implique de passer le terminal en mode raw avec process.stdin.setRawMode(true) et de gérer chaque touche.

Faut-il utiliser readline ou process.argv ?

Utilisez process.argv quand les valeurs sont connues avant le démarrage du programme, pour qu'il puisse tourner dans un script sans personne devant. Utilisez readline pour les outils interactifs qui posent une question après l'autre.

Illustration des langages de programmation de Coddy

Apprendre à coder avec Coddy

Commencer