Évitez les dépendances circulaires avec le SDP
Les dépendances circulaires sont des tueurs silencieux. Elles ne provoquent pas d'erreurs de build. Elles ne provoquent pas d'exceptions d'exécution lors de l'importation. Au lieu de cela, elles engendrent des valeurs undefined subtiles qui n'apparaissent en production que des semaines plus tard.
Un cycle se produit lorsque le module A importe de B, et que B importe en retour de A.
JavaScript résout ces importations silencieusement. Si le module A est encore en cours de chargement lorsque le module B le demande, JavaScript renvoie un objet vide. Votre code échoue plus tard, et la stack trace pointe vers le mauvais endroit.
Vous pouvez corriger cela avec dependency-cruiser. Cet outil analyse vos fichiers et cartographie votre graphe de dépendances. Il fonctionne avec TypeScript et les monorepos.
Comment le configurer :
- Ajoutez-le à vos dépendances de développement : yarn add -D dependency-cruiser
- Ajoutez un script à votre package.json : "depcruise": "depcruise packages --config .dependency-cruiser.js"
- Créez un fichier .dependency-cruiser.js pour détecter les cycles.
Mais trouver un cycle n'est que la moitié du combat. Vous devez empêcher leur formation.
Utilisez le Stable Dependencies Principle (SDP). Cette règle stipule que vous devez dépendre dans le sens de la stabilité.
La stabilité est une propriété structurelle. Un module est stable lorsque de nombreux autres modules en dépendent. Si vous modifiez un module stable, vous affectez beaucoup de monde. Ce coût est ce qui le rend stable.
Utilisez la formule d'instabilité : I = Fan-Out / (Fan-In + Fan-Out)
• I = 0 signifie qu'un module est au maximum de sa stabilité. Tout en dépend, et il ne dépend de rien. • I = 1 signifie qu'un module est au maximum de son instabilité. Il dépend de beaucoup de choses, et rien ne dépend de lui.
La règle : le score d'instabilité d'un module doit être supérieur au score de chaque module qu'il importe. Vos flèches doivent pointer vers une instabilité moindre.
Vos utilitaires de bas niveau (I ≈ 0) ne devraient jamais importer de vos pages de haut niveau (I ≈ 1).
Vous pouvez transformer ce principe en une règle automatisée avec dependency-cruiser. Au lieu de simplement vérifier les cycles, vérifiez la direction :
- Empêchez les utils d'importer des features.
- Empêchez les features d'importer des pages.
Cela stoppe les conditions structurelles qui créent des cycles. Vous cessez de réagir aux bugs pour commencer à les prévenir.
