Communitygithub.com

Utiliser les dépendances de manière idiomatique

Apprenez à utiliser les bibliothèques et frameworks d'un projet comme ils ont été conçus, en exploitant leur modèle plutôt que de réinventer la roue ou de lutter contre le framework.

Qu'est-ce que Utiliser les dépendances de manière idiomatique ?

Cette compétence guide le développeur ou l'agent IA à écrire du code qui utilise les dépendances d'un projet de manière idiomatique, c'est-à-dire en respectant le modèle et les API publiques de chaque bibliothèque ou framework. Elle aide à éviter les pièges courants comme réinventer la roue, lutter contre le framework ou sous-utiliser les fonctionnalités existantes. Le processus se déroule en six étapes : reformuler le problème, vérifier si la solution n'existe pas déjà (dans le framework, le projet, les packages partagés ou la bibliothèque standard), étudier le modèle de la bibliothèque dans sa documentation officielle, choisir l'outil approprié, écrire le code en utilisant l'API publique de manière idiomatique, et gérer les frictions. La compétence inclut également une liste de « signaux d'alerte » (smells) pour détecter quand on lutte contre la bibliothèque (ex : cast de types, utilisation d'API privée, contournement de garanties) ou quand on la sous-utilise (ex : boucles manuelles là où une API batch existe, options redondantes). Elle s'applique à tout projet logiciel et à tout langage ou écosystème (Python, Node.js, Go, Rust, etc.), et est conçue pour être utilisée avant d'écrire un helper générique, lors de l'extension d'une bibliothèque, ou quand une fonctionnalité semble manquante.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/AndrewIngram/swe-skills/tree/HEAD/skills/engineering/use-dependencies-idiomatically

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Que fait Utiliser les dépendances de manière idiomatique ?

Chaque dépendance a été construite pour une forme particulière de problème. Son API encode ce modèle : ce qu'elle possède, ce qu'elle vous laisse, ce qu'elle garantit et où elle attend d'être étendue. Écrivez la solution idiomatique, celle que la documentation et les exemples canoniques de la bibliothèque montreraient, et lorsque le problème a une forme différente (un décalage d'impédance), choisissez l'outil adapté à la tâche. Les échecs à éviter sont réinventer la roue, lutter contre le framework et sous-utiliser silencieusement une fonctionnalité conçue pour ce cas.

La friction est une odeur : un cast, un correctif ou un contournement sur le chemin évident signifie que le modèle est mal interprété ou que l'outil est inapproprié. Les violations les plus coûteuses n'ont aucune friction : elles passent la vérification de type et semblent locales tout en annulant une garantie que la bibliothèque existe pour fournir. Cherchez-les donc délibérément.

Écrire du code utilisant une dépendance

Le chemin par défaut. La revue, l'audit, l'ajout et la mise à niveau en découlent (ci-dessous).

  1. Reformulez le problème. Méfiez-vous du problème XY : la tâche arrive souvent comme une solution, de votre part ou de celle de l'utilisateur. Reformulez-la comme le problème général :

    • « Réessayer le téléchargement trois fois » est une politique de réessai.
    • « J'ai besoin de row_number() over (partition by account_id) pour les dernières factures de chaque compte » est top-N par groupe, ce qu'un ORM peut modéliser sans fonction de fenêtrage.

    « La bibliothèque ne peut pas faire X » est une affirmation à vérifier à l'étape 3, quel que soit son auteur.

    Terminé lorsque vous pouvez nommer le problème dans les mots que la documentation de la bibliothèque utiliserait.

  2. Trouvez où il est déjà résolu, d'abord le plus proche :

    1. Le framework dans lequel vous vous trouvez : les politiques de réessai et les minuteurs d'un moteur de workflow, la pagination et les mises à jour de store d'un client GraphQL, les faux minuteurs d'un test runner.
    2. Les dépendances déclarées du projet (package.json, pyproject.toml, go.mod, Cargo.toml) et comment la base de code les importe. L'utilisation existante montre la convention de l'équipe, qui peut différer de la conception de la bibliothèque.
    3. Les packages partagés du projet, qui enveloppent souvent une dépendance de la manière dont le projet souhaite l'utiliser.
    4. La bibliothèque standard, pour la version d'exécution en cours d'utilisation (engines, .nvmrc, requires-python). Les bibliothèques larges couvrent plus que ce que les gens se rappellent : itertools, collections, functools, pathlib de Python ; fetch, AbortSignal.timeout, util.parseArgs, node:test de Node moderne.

    Terminé lorsque chaque source a été vérifiée et que vous avez une liste restreinte, éventuellement vide.

  3. Apprenez le modèle à partir de la documentation de la version installée. Prenez la version du fichier de verrouillage (lockfile) ; une source ne compte que si elle correspond. Lisez, dans l'ordre :

    1. Les recommandations du projet pour cette dépendance, trouvées et conservées selon GUIDANCE.md. C'est l'autorité sur les décisions délibérées de l'équipe et un cache du modèle de la bibliothèque : lorsque sa version enregistrée diffère du lockfile, ou qu'une affirmation décide de votre approche, confirmez-la dans les sources ci-dessous.
    2. Un dépôt de référence : le dépôt de la dépendance cloné dans le projet ou récupéré par un outil tel que opensrc, généralement avec un pointeur dans AGENTS.md ou CLAUDE.md. Vérifiez son tag par rapport au lockfile. Sa documentation, ses exemples et ses tests sont le meilleur enregistrement de l'utilisation prévue.
    3. Le package installé : les types exportés et leurs commentaires de documentation, souvent dépourvus de documentation et d'exemples.
    4. En ligne, lorsque ni l'un ni l'autre des deux derniers n'a de documentation : la documentation officielle pour cette version majeure, les pages de concepts et de guides ainsi que la référence API ; puis le dépôt en amont au tag correspondant.

    Construisez uniquement sur l'API publique : ce que la documentation décrit, accessible via les points d'entrée déclarés (une carte exports, __all__, les noms sans underscore en tête). Lisez le code source pour comprendre le comportement ; tout ce que vous n'y avez trouvé que là est privé. Semver protège l'API publique et rien d'autre. Votre mémoire de la bibliothèque est une hypothèse à vérifier par rapport à la documentation, et les fichiers d'exécution que vous ouvrez par hasard ne la remplacent pas.

    Terminé lorsque vous pouvez répondre, à partir de la documentation, avant d'écrire ou de juger du code qui l'utilise :

    • À quoi servait-elle et qu'est-ce qu'elle omet délibérément ?
    • Que possède-t-elle (stockage, cache, cycle de vie, réessais, transactions), que génère-t-elle ou vous demande-t-elle de déclarer (sortie de génération de code, schémas, types), et à quelle partie de votre code chaque élément est-il destiné ?
    • Quelle garantie maintient-elle (masquage de données, déterminisme du workflow, isolement des transactions), entre quelles parties du système, et qu'est-ce qui la contrecarrerait silencieusement ? Elle se situe souvent entre vos propres modules.
    • Quelle API publique et quels points d'extension documentés (options, plugins, middleware, hooks, échappatoires) couvrent cela, et à quoi ressemble l'exemple canonique, jusqu'à quel module importe quoi ?
    • Quelles vérifications fournit-elle (un plugin de lint, une validation du compilateur ou du générateur de code, un mode de type strict), et le projet les exécute-t-il ?
  4. Choisissez l'adéquation :

    • Le problème correspond au modèle : utilisez-le.
    • Une partie tombe en dehors de l'API principale : utilisez l'échappatoire documentée pour cette partie (SQL brut dans un ORM, un composant sans tête, un résolveur personnalisé). Les échappatoires font partie de la conception.
    • La version installée ne l'a pas : si le journal des modifications montre qu'une version plus récente l'a, proposez la mise à niveau selon UPGRADING.md.
    • Décalage d'impédance : utilisez une dépendance dont le modèle correspond, ou du code simple qui reste à l'écart de celle-ci, derrière une couture que nous possédons. Être installé ou utilisé à proximité ne fait pas d'une bibliothèque l'outil approprié.

    Terminé lorsque vous en avez choisi un et pouvez le justifier à partir du modèle.

  5. Écrivez-le à la manière de la bibliothèque, sur son API publique. La première version qui fonctionne n'est souvent pas la version idiomatique. Lorsque le code voisin et l'exemple canonique divergent, suivez l'exemple canonique et informez l'utilisateur de la dérive. Exécutez les propres vérifications de la bibliothèque au fur et à mesure ; si le projet les omet, dites ce que leur activation détecterait.

    Terminé lorsque les vérifications de la bibliothèque réussissent, qu'aucune odeur ci-dessous ne s'applique (ou que chacune qui s'applique est un choix que vous signalerez), et que les mainteneurs de la bibliothèque reconnaîtraient le code comme leur bibliothèque utilisée comme conçue.

  6. Lorsque la friction persiste, adaptez d'abord notre conception au modèle de la bibliothèque ; ses contraintes codent souvent une leçon (les règles de déterminisme d'un moteur de workflow, le masquage de données d'un client GraphQL). Revisitez ensuite l'étape 4. Travaillez contre la bibliothèque uniquement avec l'accord de l'utilisateur, en nommant le comportement non documenté sur lequel vous vous appuyez dans la proposition et dans un commentaire au niveau du contournement. Un conflit entre le modèle et une exigence produit est la décision de l'utilisateur.

Odeurs : lutter contre la bibliothèque

Chacune vous renvoie à l'étape 4. Classez par ce que la bibliothèque est là pour fournir : une garantie annulée a priorité sur tout le reste, même si rien n'est cassé aujourd'hui, et une règle maison qui code le modèle prend la sévérité du modèle.

  • Garantie annulée : code généré utilisé en dehors du module pour lequel il a été généré (types de fragments d'un autre composant), lecture de données masquées d'un autre module, un fragment ou schéma partagé entre des appelants non liés, non-déterminisme à l'intérieur d'un workflow déterministe. Ceux-ci passent la vérification de type proprement, alors cherchez-les délibérément.
  • Casts ou suppressions du vérificateur de type (as, any, @ts-expect-error, # type: ignore) là où notre code rencontre les types de la bibliothèque.
  • API privée : chemins internes (pkg/dist/…, pkg._internal), noms avec underscore, exports non documentés, casts dans les champs privés d'un objet de bibliothèque, comportement trouvé uniquement dans le code source. Une API instable ou expérimentale est documentée mais en dehors de semver : utilisez-en une lorsque la documentation le recommande ici, et dites-le.
  • Un correctif qui modifie le comportement de la bibliothèque (correctif du gestionnaire de packages, monkey-patching, fork vendu). Un correctif qui fait faire à la bibliothèque ce que sa documentation promet déjà est une correction de bug et la bonne chose à faire : limitez-le à la correction et liez le problème en amont.
  • État dupliqué : une deuxième source de vérité pour quelque chose que la bibliothèque possède, comme un cache GraphQL reflété dans l'état du store ou des compteurs de réessai que le framework suit déjà.
  • Minuteurs, drapeaux ou chaînes d'effets qui exécutent du code « après » la bibliothèque, alors qu'elle offre un callback, un événement ou un hook.
  • Une valeur par défaut remplacée à chaque site d'appel, ou un wrapper qui annule un comportement à chaque appel.
  • Un wrapper superficiel qui renomme principalement l'API qu'il enveloppe. Appliquez le test de suppression : si le supprimer ne fait que déplacer ses appels vers la bibliothèque, il ne justifie pas son existence.
  • Partie d'une fonctionnalité de bibliothèque reconstruite parce que l'ensemble semblait plus que ce dont vous aviez besoin.

Odeurs : sous-utiliser la bibliothèque

Le code fonctionne sur l'API publique, mais une fonctionnalité conçue pour ce cas le rendrait plus court ou plus déclaratif. Pour la trouver, lisez le type de chaque objet d'options que vous passez et le guide de la bibliothèque pour le problème de l'étape 1.

  • Plusieurs appels effectuant une seule opération : find-then-create là où il y a un upsert, écritures dans une boucle là où il y a une API batch.
  • Colle transformant la sortie, alors que la requête ou le hook prend une option select ou projection.
  • État que la bibliothèque suit, reconstruit à la main : drapeaux de chargement, en attente, modifié ou de réessai.
  • Les mêmes options à chaque site d'appel, alors qu'il existe des valeurs par défaut, une configuration partagée, un thème ou une fabrique.
  • Code impératif pour quelque chose que la bibliothèque vous permet de déclarer : un schéma, une variante, une relation, une politique.

La proportion joue dans les deux sens : lorsque quelques lignes claires de code simple font le travail, le code simple est idiomatique.

Revue, audit, ajout et mise à niveau

  • Revoir le changement de quelqu'un d'autre : lisez REVIEWING.md.
  • Auditer l'utilisation d'une dépendance dans une base de code : lisez AUDITING.md.
  • Ajouter un package, ou mettre à niveau une dépendance ou l'exécution : lisez UPGRADING.md d'abord.
  • Trouver, écrire ou mettre à jour les recommandations du projet pour une dépendance : lisez GUIDANCE.md.

Répondez : les fonctionnalités de la bibliothèque qui portent le comportement que vous n'avez pas écrit ; pour le code à usage général que vous avez écrit vous-même, ce que vous avez vérifié et pourquoi rien ne correspondait ; chaque dépendance que vous avez écartée, et la partie de son modèle qui ne correspondait pas ; et chaque odeur que vous avez conservée, avec la raison. Lorsque vous avez appris quelque chose de durable sur la dépendance, ajoutez les recommandations que vous proposez, selon GUIDANCE.md.

Skills associés