Configuration CI pratique pour les projets Node.js
Tout projet Node.js atteint un stade où les tests manuels deviennent peu fiables. Quelqu’un oublie d’exécuter le linter avant de pousser son code. Les tests passent en local mais échouent sur la machine d’un coéquipier. Une mise à jour de dépendance casse la production car personne n’a détecté l’incompatibilité.
Un pipeline CI bien structuré détecte ces problèmes automatiquement. Cet article explique à quoi ressemble une configuration CI Node.js solide et de référence avec GitHub Actions, pourquoi chaque composant existe, et comment réfléchir aux différentes pièces pour que votre pipeline vieillisse bien.
Points clés à retenir
- Utilisez
npm ciau lieu denpm installdans les pipelines CI pour des builds déterministes et reproductibles basés sur votre fichier de verrouillage - Structurez votre pipeline pour échouer rapidement : installer les dépendances → linter et vérifier les types → exécuter les tests
- Testez sur les versions Node.js que vous supportez réellement en utilisant une matrice de versions, en vous concentrant sur les versions LTS actives
- Exécutez l’analyse statique avant les tests pour détecter les erreurs rapidement et produire des messages d’échec plus clairs
- Gardez votre pipeline simple et maintenable en évitant un cache sur-ingénéré et un verrouillage excessif des versions
Ce qu’un pipeline CI JavaScript de base devrait faire
Un pipeline CI pratique pour les projets Node.js gère trois préoccupations : assurer la cohérence des dépendances, valider la qualité du code et exécuter les tests sur les versions Node pertinentes.
Le pipeline doit échouer rapidement et de manière visible. Si quelque chose casse, les développeurs doivent le savoir immédiatement et comprendre pourquoi.
Les étapes principales
Un workflow CI Node fiable avec GitHub Actions suit cette séquence :
Installer les dépendances → Linter et vérifier les types → Exécuter les tests
Chaque étape conditionne la suivante. Il est inutile d’exécuter une suite de tests complète si le code ne se parse même pas correctement.
Installation des dépendances : pourquoi npm ci est important
La meilleure pratique npm CI la plus importante est d’utiliser npm ci au lieu de npm install dans votre pipeline.
npm ci fait deux choses importantes pour la CI :
- Il installe exactement ce qui se trouve dans votre fichier de verrouillage — pas de résolution de version, pas de surprises
- Il supprime d’abord
node_modules, garantissant un environnement propre
Ce comportement déterministe signifie que votre environnement CI correspond à ce que spécifie votre fichier de verrouillage. Lorsqu’un build échoue, vous savez que l’échec n’est pas causé par une dérive des dépendances.
Votre fichier de verrouillage (package-lock.json pour npm, pnpm-lock.yaml pour pnpm, yarn.lock pour Yarn) doit être commité dans votre dépôt. Sans lui, npm ci ne fonctionnera pas et vous perdez la reproductibilité.
Gérer les gestionnaires de paquets avec Corepack
Si votre équipe utilise pnpm ou Yarn, Corepack gère le versionnement du gestionnaire de paquets. Activez-le dans votre workflow avant d’installer les dépendances. Cela garantit que tout le monde — y compris la CI — utilise la même version de gestionnaire de paquets spécifiée dans votre package.json.
Matrices de versions : tester sur plusieurs versions Node
Une matrice de versions vous permet d’exécuter votre pipeline sur plusieurs versions Node.js simultanément. Pour la plupart des projets, tester sur la version LTS active est suffisant. Les projets avec des exigences de compatibilité plus larges peuvent ajouter la LTS de maintenance actuelle.
L’approche par matrice détecte les problèmes de compatibilité tôt. Une fonctionnalité syntaxique qui fonctionne dans les versions Node plus récentes peut ne pas exister dans les versions plus anciennes dont dépendent vos utilisateurs.
Gardez votre matrice minimale. Tester sur toutes les versions possibles ajoute du temps CI sans bénéfice proportionnel. Concentrez-vous sur les versions que votre projet supporte réellement.
Discover how at OpenReplay.com.
Linting et vérification de types avant les tests
Exécutez l’analyse statique avant votre suite de tests. ESLint détecte les problèmes de qualité de code. TypeScript (si vous l’utilisez) détecte les erreurs de type. Les deux s’exécutent plus rapidement que la plupart des suites de tests.
Cet ordre est important pour deux raisons :
- Retour plus rapide : les erreurs de syntaxe apparaissent en quelques secondes, pas en minutes
- Échecs plus clairs : une erreur de linting est plus facile à diagnostiquer qu’un échec de test cryptique causé par le même problème sous-jacent
Configurez ces outils pour faire échouer le build en cas d’erreurs. Les avertissements qui ne font pas échouer le build sont ignorés.
Exécution des tests et visibilité des échecs
Votre étape de test doit produire une sortie claire. Lorsque les tests échouent, les développeurs doivent identifier le problème rapidement — idéalement sans fouiller dans des sections de logs repliées.
La plupart des lanceurs de tests supportent des formats de sortie adaptés à la CI. Jest, Vitest et le lanceur de tests intégré à Node détectent tous les environnements CI et ajustent leur sortie en conséquence.
Considérez ces pratiques :
- Exécutez les tests avec couverture uniquement lorsque vous utiliserez réellement les données de couverture
- Parallélisez les fichiers de test si votre lanceur le supporte et que vos tests sont indépendants
- Échouez rapidement sur les branches de développement et exécutez la suite complète sur main
Cache : une note sur les attentes
La mise en cache des dépendances peut réduire les temps d’installation, mais les bénéfices varient. Les petits projets avec peu de dépendances peuvent voir une amélioration minimale. Les grands monorepos peuvent économiser plusieurs minutes par exécution.
Ne sur-ingéniez pas le cache. Le cache intégré dans actions/setup-node gère les cas courants. Si vos installations sont lentes, mesurez avant d’ajouter de la complexité.
Garder votre pipeline maintenable
Un pipeline CI qui nécessite des mises à jour constantes devient un fardeau. Évitez de verrouiller les versions d’actions sur des patchs spécifiques — utilisez des tags de version majeure qui reçoivent des mises à jour compatibles. Référencez les versions Node par leur ligne de version plutôt que par des versions exactes lorsque c’est possible.
L’objectif est un pipeline CI JavaScript qui s’exécute de manière fiable sans maintenance fréquente. Lorsque vous devez le mettre à jour, les changements doivent être intentionnels, pas réactifs.
Conclusion
Une configuration CI Node.js solide ne nécessite pas de configuration élaborée. Installez les dépendances de manière déterministe avec npm ci, exécutez l’analyse statique avant les tests, et testez sur les versions Node que vous supportez. Rendez les échecs visibles et gardez le pipeline suffisamment simple pour le maintenir.
Commencez avec cette base de référence. N’ajoutez de la complexité que lorsque vous avez un problème spécifique à résoudre.
FAQ
npm ci installe exactement ce que spécifie votre fichier de verrouillage sans résoudre les versions, et il supprime d'abord node_modules pour un environnement propre. npm install peut mettre à jour le fichier de verrouillage et résoudre différentes versions. Pour la CI, npm ci fournit des builds déterministes qui correspondent exactement à votre fichier de verrouillage commité.
Testez sur les versions que votre projet supporte réellement. Pour la plupart des projets, la version LTS active est suffisante. Ajoutez la LTS de maintenance si vous avez besoin d'une compatibilité plus large. Évitez de tester toutes les versions possibles car cela ajoute du temps CI sans bénéfice proportionnel.
Le linting s'exécute plus rapidement que la plupart des suites de tests et détecte les problèmes de syntaxe et de qualité de code en quelques secondes. L'exécuter en premier fournit un retour plus rapide et produit des messages d'échec plus clairs. Une erreur de linting est plus facile à diagnostiquer qu'un échec de test cryptique causé par le même problème sous-jacent.
Cela dépend de la taille de votre projet. Les petits projets avec peu de dépendances voient une amélioration minimale avec le cache. Les grands monorepos peuvent économiser plusieurs minutes par exécution. Commencez avec le cache intégré dans actions/setup-node et mesurez les temps d'installation réels avant d'ajouter de la complexité.
Understand every bug
Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.