Neuf paquets utilitaires Node.js à installer avant de commencer à coder
Découvrez comment un petit ensemble de paquets Node.js – couvrant la configuration de l’environnement, la validation, l’écriture de scripts, la gestion des processus et le journalisation – peut permettre d’éliminer rapidement les bugs courants.
Tout nouveau projet Node a tendance à suivre le même schéma : un répertoire vide, un seul fichier index.js, et la croyance naïve que la bibliothèque standard couvrira la plupart des besoins. Quelques jours plus tard, on se retrouve à écrire soi-même des boucles de tentative manuellement, à parser les dates avec des expressions régulières, et à créer encore un chargeur .env légèrement différent.
À un certain moment, il devient logique de cesser à inventer sans cesse ces solutions et de recourir plutôt à un petit ensemble d’outils cohérent avant d’écrire toute logique réelle. Aucun de ces paquets n’est spectaculaire. Chacun élimine discrètement une catégorie de bugs que l’on a souvent tendance à considérer comme un coût inévitable de la création de logiciels. Voici neuf outils qui méritent d’être installés tôt dans n’importe quel projet.
1. dotenv
Si vous avez déjà mis par erreur une clé API dans un répertoire Git, vous comprenez déjà l’intérêt de ce package. dotenv charge des paires clé-valeur à partir d’un fichier .env dans process.env, en conservant les informations sensibles dans un fichier hors du contrôle de version plutôt que d’être intégrées directement dans votre code.
// .env
DATABASE_URL=postgres://localhost:5432/mydb
STRIPE_SECRET_KEY=sk_test_...
// index.js
import "dotenv/config";
const db = connect(process.env.DATABASE_URL);
C’est un package minimal avec une fonctionnalité restreinte, mais il fait la différence entre avoir toute votre configuration en un seul endroit prévisible et la disperser dans plusieurs fichiers ainsi que dans un message caché dans une ancienne discussion.
2. zod
La validation de schéma en temps de exécution est facile à négliger lorsque quelques instructions if semblent suffire. Cette confiance disparaît généralement dès que une requête mal formatée parvient à contourner ces vérifications et atteint l’environnement de production.
zod vous permet de définir la structure des données une seule fois et d’en déduire à la fois un validateur en temps de exécution ainsi qu’un type TypeScript correspondant :
import { z } from "zod";
const CreateUserSchema = z.object({
email: z.string().email(),
age: z.number().min(13),
});type CreateUser = z.infer<typeof CreateUserSchema>;app.post("/users", (req, res) => {
const result = CreateUserSchema.safeParse(req.body);
if (!result.success) {
return res.status(400).json({ error: result.error.flatten() });
}
// result.data is now typed and validated
createUser(result.data);
});
Le plus grand avantage se manifeste aux frontières de votre application : les données provenant des API, les variables d’environnement, les fichiers de configuration, et tout autre élément extérieur à vos systèmes qui entre dans votre application. En validant ces données aux points d’entrée, le reste de votre code peut supposer en toute sécurité que les données reçues ont la structure attendue.
3. tsx
Tout développeur utilisant TypeScript a probablement rencontré les contraintes liées à l’exécution d’un script unique : compiler avec tsc avant d’exécuter le résultat, ou configurer ts-node et attendre son temps de démarrage. tsx élimine complètement ces contraintes en exécutant directement les fichiers .ts, sans étape de compilation ni configuration requise.
tsx scripts/migrate-users.ts
Il n’a pas été conçu pour remplacer un pipeline de construction en production. Il a été créé pour les dizaines de petits scripts que chaque base de code accumule avec le temps, tels que des migrations ponctuelles, des scripts de génération de données initiales ou des vérifications rapides de données. Ceux-ci ne nécessitent pas une configuration complète de construction ; ils doivent simplement s’exécuter presque instantanément afin de ne pas perdre de temps à attendre un compilateur.
4. execa
Le module intégré de Node, child_process, permet d’accomplir cette tâche, mais l’utiliser correctement signifie devoir gérer manuellement stdout, stderr, les codes de sortie et les erreurs à chaque fois. execa regroupe tout cela dans une interface qui fonctionne comme on s’y attend naturellement :
import { execa } from "execa";
const { stdout } = await execa("git", ["rev-parse", "--short", "HEAD"]);
console.log(`Current commit: ${stdout}`);
Les erreurs sont levées comme il se doit au lieu de provoquer des échecs silencieux, les résultats sont automatiquement tronqués pour vous, et le support async/await est intégré sans avoir besoin d’écrire votre propre enveloppe de promesse autour de spawn. Pour toute personne qui crée des outils CLI ou des scripts appelant d’autres programmes, ce seul package élimine toute une catégorie de bugs où quelque chose ne fonctionne pas silencieusement et vous laisse deviner pourquoi.
5. p-retry
Les réseaux sont peu fiables. Les API imposent des limites de vitesse. Les connexions aux bases de données tombent parfois pour des raisons jamais entièrement expliquées. p-retry enrobe toute fonction asynchrone avec une logique de tentative répétée et un retard exponentiel, afin qu’une requête instable ne fasse pas planter tout votre processus :
import pRetry from "p-retry";
const data = await pRetry(() => fetchFromFlakyApi(url), {
retries: 5,
onFailedAttempt: (error) => {
console.log(`Attempt ${error.attemptNumber} failed. Retrying...`);
},
});
Il est courant de devoir écrire ce type de logique manuellement pour chaque projet, généralement avec des erreurs, et souvent sans mécanisme de recul approprié, ce qui peut aggraver encore la situation d’une API en difficulté par des tentatives répétées rapides. Ce package gère cela correctement en seulement quelques lignes, et il a permis à plus d’une intégration de ne pas échouer complètement lors d’une panne courante sur un service tiers.
6. day.js
Travailler avec les dates en JavaScript pur est extrêmement compliqué, et moment.js, la bibliothèque à laquelle la plupart des gens avaient recours par défaut, est lourde et n’est plus en développement actif. day.js offre une API tout aussi pratique mais avec un encombrement bien moindre :
import dayjs from "dayjs";
const deadline = dayjs().add(3, "day").format("YYYY-MM-DD");
const isOverdue = dayjs(invoice.dueDate).isBefore(dayjs());
Le formatage des dates, leur comparaison, l’addition ou la soustraction de durées temporelles, ainsi que le parsing de chaînes de dates complexes deviennent tous très simples, ce qui signifie que l’on cesse d’introduire des erreurs subtiles dues à une erreur de un jour résultant du calcul manuel.
7. pino
console.log fonctionne bien pour de petits scripts, mais une fois que vous exécutez un service en production générant des milliers d’entrées de journal par minute, vous avez besoin d’un outil permettant un filtrage et une recherche efficaces. pino génère des journaux JSON structurés à une vitesse qui n’a presque aucun impact mesurable sur votre application :
import pino from "pino";
const logger = pino();
logger.info({ userId: user.id, action: "checkout" }, "Order placed");
Comme la sortie est structurée, quel que soit l’outil utilisé pour la consommer — Datadog, une pile ELK, ou même simplement l’utilisation de grep sur un fichier par la suite — il est possible de la parser et de la filtrer correctement. C’est bien mieux que de parcourir des pages de texte brut à la recherche de la ligne pertinente alors qu’une situation critique se produit.
8. cheerio
Parfois, tout ce dont on a besoin, c’est d’extraire une partie de données structurées à partir d’une page HTML, et lancer un navigateur sans interface semble être une surcharge excessive pour une tâche qui consiste simplement en « localiser cet élément et lire son texte ». cheerio offre une API similaire à jQuery pour parser et interroger l’HTML du côté serveur, sans aucun des inconvénients liés au démarrage d’un véritable navigateur :
import * as cheerio from "cheerio";
const $ = cheerio.load(html);
const titles = $("h2.product-title")
.map((_, el) => $(el).text().trim())
.get();
Il ne met pas en exécution de JavaScript sur la page, il ne peut donc pas remplacer un outil comme Playwright lorsque le contenu est rendu du côté client. Cependant, pour extraire du markup statique, traiter des contenus similaires à des flux ou récupérer des valeurs depuis des pages que vous contrôlez, il est bien plus rapide et moins gourmand en ressources que de lancer une instance de navigateur.
9. pm2
Démarrer votre application avec node index.js fonctionne bien tant qu’elle ne plante pas au milieu de la nuit sans que rien ne la redémarre. pm2 maintient votre processus en cours d’exécution, le redémarre automatiquement après une panne et offre un suivi de base ainsi que la gestion des journaux, tout cela sans nécessiter une plateforme complète d’orchestration de conteneurs.
pm2 start index.js --name my-api
pm2 logs my-api
pm2 restart my-api
Pour de nombreuses implémentations de petite et moyenne taille, c’est vraiment toute la supervision des processus dont vous aurez besoin. Cela ne remplacera pas Kubernetes si vous gérez un grand système distribué, mais sur un seul serveur exécutant quelques processus Node, c’est la différence entre devoir se connecter par SSH chaque fois qu’un processus tombe en panne et ne pas avoir ce problème du tout.
L’essentiel
Aucun de ces neuf paquets n’est particulièrement impressionnant en soi, et c’est justement l’essentiel à retenir. Chacun prend en charge une petite partie de la logique que l’on aurait normalement dû écrire soi-même, en commettant souvent des erreurs lors de la première tentative, avant de devoir la maintenir indéfiniment. Les utiliser ne signifie pas prendre des raccourcis ; cela consiste plutôt à diriger son attention limitée vers les parties de l’application que l’on doit véritablement construire, plutôt que de réimplémenter et de déboguer à nouveau une boucle de tentative pour le cinquième projet consécutif.
Lectures complémentaires
- Les fonctionnalités de Node.js 26 qui remplacent discrètement des années de solutions de fortune — Une présentation de l’API Temporal de Node.js 26, de l’exécution native de TypeScript, des outils d’optimisation du cache et d’autres ajouts qui éliminent des solutions de fortune existantes depuis longtemps.