Recherche/Maintenir une bibliothèque CSS-in-JS qui fonctionne sur navigateur, serveur et natif

Maintenir une bibliothèque CSS-in-JS qui fonctionne sur navigateur, serveur et natif

À utiliser quand une IA de code travaille sur une bibliothèque CSS-in-JS conforme aux standards. Elle limite les styles au CSS standard, évite les pannes selon l'environnement, écrit d'abord les tests selon la spécification et cadre notes de version, doc et démos avec du vrai code.

Pour utiliser ces règles d'IA
## N'accepter que du CSS standard dans les styles et donner la priorité aux valeurs par défaut configurées Maintenez la surface de style rédigée alignée sur du CSS réel, conforme aux standards. Cela garde le modèle mental transposable et empêche l'API de dériver vers un dialecte idiosyncratique. - N'acceptez dans les styles rédigés que des noms, orthographes et valeurs de propriétés standards. N'inventez jamais d'alias non standards (par exemple des noms en kebab-case pour des props propres à une plateforme). Les clés de style spécifiques à une plateforme doivent passer par une échappatoire explicite (un objet de style inline, ou un support en amont côté plateforme), pas par le langage de template. - Le rôle de la couche native est de faire correspondre du CSS idiomatique à des primitives de plateforme équivalentes et de fournir un polyfill pour ce qu'elle peut, en attendant que le runtime natif rattrape son retard. Elle n'est pas là pour élargir la grammaire d'entrée acceptée. ### Priorité des valeurs par défaut configurées - Les valeurs par défaut d'attributs configurées par l'auteur l'emportent toujours sur les props passées par l'appelant, par conception. Il s'agit d'un contrat délibéré, pas d'un bug. - L'échappatoire est la forme fonction de la configuration des valeurs par défaut : elle reçoit les props entrantes et peut se replier de façon conditionnelle (conserver la valeur de l'appelant, ou fournir une valeur par défaut). - Exception : un appelant passant explicitement `undefined` pour une prop supprime la valeur par défaut configurée pour cette prop. ## Utiliser le gestionnaire de paquets et le format de commit du projet - Au début de chaque session, lisez le résumé des fonctionnalités actuellement exposées aux consommateurs, afin de travailler sur la surface réellement supportée aujourd'hui, et non sur un comportement mémorisé. - Utilisez le gestionnaire de paquets désigné par le projet ainsi que ses commandes associées ; n'en substituez pas un autre. - Ne démarrez jamais le serveur de développement vous-même. Demandez au mainteneur de le démarrer si besoin. - Utilisez les préfixes de commit conventionnels (`feat|fix|chore|refactor|test|docs|style|perf|build|ci`). Privilégiez par défaut des messages courts : uniquement un titre, ou un titre plus une phrase concise. - Conservez une convention d'orthographe anglaise cohérente pour toute la prose (commentaires, documentation, titres de tests, chaînes visibles par l'utilisateur). Ne préservez l'orthographe d'origine qu'à l'intérieur de citations exactes issues de spécifications ou de standards. ## Distinguer serveur, navigateur et natif, et garder le code DOM hors du natif Le code livré sur plusieurs runtimes ne doit jamais présumer d'un seul environnement. Détectez l'environnement à partir de plusieurs signaux indépendants et isolez le code incompatible à la frontière du point d'entrée. - Ne réduisez pas la détection d'environnement à un seul indicateur universel. Distinguez au minimum : une constante serveur définie au moment du build (vraie uniquement dans le build serveur), une condition de composant serveur au runtime (certains frameworks servent un build sans les API de contexte réservées au client), et un indicateur serveur par requête défini par le point d'entrée SSR. Chaque décision se conditionne au sous-ensemble minimal de signaux qui couvre les scénarios qui la concernent. Piège courant : supprimer le travail DOM uniquement sur la base de la constante serveur définie au build casse le chemin de test « build serveur sous jsdom », où des mutations DOM se produisent quand même. Conditionnez plutôt les décisions liées au DOM sur les signaux de runtime/SSR. - Le point d'entrée natif ne doit jamais importer transitivement du code DOM/navigateur via des imports de valeur. Utilisez des imports de type uniquement et des marqueurs de runtime typés (un registre de symboles partagé) plutôt que `instanceof`. Vérifiez avec un grep affirmant zéro référence à `document.` dans le bundle natif construit ; certains runtimes natifs échouent au moment de l'évaluation du module dès qu'une référence à `document` est présente. - Les hooks de framework qui n'existent pas dans tous les runtimes (par exemple un hook de ref indéfini dans les composants serveur) doivent être conditionnés par la constante serveur définie au build, pour permettre l'élimination de code mort. Ne les protégez jamais par une vérification runtime de type `typeof hook === 'function'`, ce qui devient un appel de hook conditionnel. - Conservez un unique chemin canonique d'émission de sortie. Lorsque vous modifiez la sortie, étendez les suites de tests d'émission et de parseur/compilateur plutôt que d'ajouter un chemin parallèle. ## Retirer du code avec des constantes de build et figer par des tests le mappage des points d'entrée Séparez ce que le bundler peut éliminer au moment du build de ce qui n'existe qu'au runtime, et soyez délibéré quant au mappage des points d'entrée. - Les constantes de build (build serveur, build natif, variante native-web, mode dev) sont substituées par des littéraux afin que les bundlers éliminent par élimination de code mort la branche inutile. Privilégiez l'encapsulation de la région contiguë la plus externe réservée au dev dans une seule garde de dev ; ne comptez pas uniquement sur un helper d'avertissement pour ignorer le travail, et ne construisez jamais de chaînes de message ou d'arguments d'avertissement en dehors de la garde de dev. - Une vérification au runtime comme `typeof window !== 'undefined'` ne peut pas être « tree-shakée ». Utilisez des constantes de build, pas des vérifications au runtime, lorsque vous avez besoin que du code soit physiquement retiré d'un bundle. - Le mappage des points d'entrée/sous-chemins est une source fréquente de rupture silencieuse. La résolution par extension de plateforme (laisser le bundler natif choisir un fichier propre à chaque plateforme) est plus sûre qu'une map d'objet `browser` que certains bundlers natifs appliquent sur toutes les plateformes, ce qui peut router silencieusement un pont web vers le natif. Un repli `.js` doit être le pont multiplateforme sûr, jamais le moteur spécifique à une plateforme. Verrouillez ces résolutions avec un test de résolution/tree-shake. - Privilégiez un champ `browser` plutôt que des `exports` conditionnels lorsque ces derniers cassent la résolution de types dans les projets composites. Ajoutez chaque répertoire de sous-chemin publié à la liste `files` du paquet. ## Écrire d'abord un test qui échoue et mesurer les optimisations sur des charges réelles - Le développement piloté par les tests strict est appliqué dans tout le dépôt. Avant de modifier du code de production, ajoutez ou étendez un test en échec qui encode le contrat souhaité, puis implémentez seulement ce qu'il faut pour le faire passer au vert. Aucun comportement visible par l'utilisateur n'est livré sans un test qui échouerait sans le changement. Appliquez la même discipline rouge-vert pour le travail hors fonctionnalité. - Effectuez toujours un microbenchmark des optimisations par rapport à une charge de travail réaliste, pas un cas synthétique idéal. Annulez tout changement qui dégrade le chemin réellement emprunté par les appelants, même s'il gagne isolément. - Optimisez pour une faible pression mémoire et des fonctions monomorphes. - Fondez tout comportement adossé à une spécification sur le brouillon d'éditeur actuel et faisant autorité de cette spécification, jamais sur des résumés, des sites de référence ou la mémoire. Récupérez à nouveau la section concernée pour la session, citez la clause normative mot pour mot en commentaire au-dessus du test qui la verrouille, et écrivez un test par règle dans un bloc de conformité à la spécification clairement nommé. Si la spécification est silencieuse ou ambiguë, documentez l'écart à côté du test et liez le ticket de suivi. Cela s'applique à tout changement touchant une spécification. ## Transformer chaque règle de la spécification en test avant de créer un polyfill natif Lorsque le moteur de style du runtime natif ne peut pas comprendre une fonctionnalité CSS, fournissez un polyfill, mais verrouillez le comportement sur la spécification avant de refactoriser l'interne. Procédure pour un polyfill nouveau ou révisité (également pour tout bloc de validation adossé à une spécification) : 1. Récupérez le brouillon d'éditeur actuel pour la session. Les numéros de clause et la formulation évoluent, ne traitez donc jamais un extrait ancien comme faisant autorité. 2. Traduisez chaque règle de la spécification en exactement un test, avec le texte exact de la spécification cité au-dessus, dans un bloc de conformité à la spécification nommé, dans la suite concernée. 3. Écrivez d'abord les tests, et notez lesquels échouent actuellement. 4. Implémentez jusqu'à ce qu'ils passent. Ne remodelez pas des tests qui passent pour les faire correspondre à l'implémentation ; la spécification fait foi. 5. Exécutez les suites natives et principales complètes pour détecter les régressions. Une fois le bloc de spécification au vert, l'interne (tokenisation, AST, évaluateur) est libre d'être refactorisé ; le bloc verrouille le comportement observable par l'utilisateur. - Maintenez le registre de compatibilité native destiné aux consommateurs à jour chaque fois que des versions de runtime sont livrées, que le support change, ou que des polyfills sont ajoutés, retirés ou modifiés. - Une fonctionnalité sans contournement natif viable doit émettre un avertissement dédupliqué avec un code stable qui nomme la construction fautive, explique pourquoi elle ne peut pas s'exécuter, et propose une alternative concrète, puis abandonner la déclaration (se replier sur null) plutôt que de livrer n'importe quoi. - Parité des variantes : lorsque le navigateur expose déjà une fonctionnalité, faites passer le CSS brut inchangé ; n'émettez jamais une propriété que le navigateur n'expose pas encore ; conditionnez les remontées de props réservées au natif et les extensions d'énumération par la constante de build réservée au natif. Donnez à chaque bloc de spécification de polyfill une sous-suite de parité qui bascule la variante web et verrouille sa sortie visible, et exemptez explicitement (avec la même rigueur qu'un commentaire d'écart) toute règle normative qui ne s'applique pas sur une variante donnée. ## Ne décrire dans les notes de version que ce que voit l'utilisateur et ranger chaque doc au bon endroit Adaptez le registre et le contenu de chaque artefact à son public. - Le texte destiné aux consommateurs (notes de version, entrées de changelog, descriptions de PR, documentation publique) n'énonce que le comportement observable par l'utilisateur, avec des mots compréhensibles par quelqu'un qui n'a pas lu le code source. Nommez ce qui est supporté et ce qui ne l'est pas, ainsi que la limite propre au changement ; renvoyez vers la matrice de compatibilité plutôt que de cataloguer des lacunes non liées. Aucun nom d'API interne, mécanisme ou chemin de code ; cela vit dans le corps du commit et le guide du contributeur. - Décrivez le comportement tel qu'il est actuellement. Évitez la narration chronologique (« auparavant », « ne fait plus », « désormais », « remplace ») pour des états qu'aucune version publiée n'a jamais livrés ; intégrez un correctif sur une fonctionnalité encore non publiée dans la note de version de cette fonctionnalité elle-même. - Ne créez des notes de version que pour des changements visibles par l'utilisateur (correctifs, fonctionnalités, changements cassants). Omettez les refactorisations internes, l'outillage, les tests, et les correctifs à du code introduit dans la même version encore non publiée. - Ne modifiez pas les fichiers générés automatiquement (changelogs, cartes d'erreurs générées) ; régénérez-les via leur outil. - N'incluez pas de noms de fournisseurs d'IA spécifiques dans la documentation destinée aux contributeurs ; utilisez une formulation neutre telle que « un assistant de codage IA ». - Ne forcez pas de retour à la ligne manuel dans la prose des corps de PR, corps d'issues ou commentaires ; les paragraphes sur une seule ligne se refluent automatiquement, et les retours à la ligne forcés paraissent cassés sur mobile et dans les vues citées. Les corps de messages de commit peuvent conserver la convention des 72 colonnes. ### Placement de la documentation - Le guide du contributeur contient les règles transversales, les invariants et le savoir acquis qui n'ont pas de place naturelle dans les commentaires du code source ; un mécanisme bien décrit n'y a pas sa place. - Les documents de connaissance autonomes capturent les pièges et le savoir acquis, pas des parcours détaillés du mécanisme des fonctionnalités ; le code source fait autorité pour le mécanisme. - Le « pourquoi » au niveau du code source vit dans les commentaires/JSDoc à côté du code. Ne reformulez pas les citations de spécification dans le code source de production ou les messages d'avertissement ; les ancrages, citations normatives et justifications vivent dans le test qui verrouille le comportement. Les messages d'avertissement nomment la construction fautive et l'alternative concrète, et rien d'autre. ## Utiliser des schémas de performance mesurés et créer des démos qui exécutent le vrai code Schémas validés par microbenchmark sur un moteur JavaScript grand public (à traiter comme des hypothèses de départ ; à re-mesurer en contexte) : - La concaténation par `+=` sur des chaînes bat `array.push()` + `join()` à toutes les échelles. - L'étalement `{...props, extra}` bat `Object.assign` ou une copie par `for..in`. - `for..in` bat `Object.keys()` plus une boucle. - Mettez en cache les RegExp compilées dans une map ; une pré-vérification par `indexOf` pour éviter complètement le travail est un gain plus important. - La concaténation manuelle par `+` bat les littéraux de gabarit (template literals) dans les boucles serrées. - Construire des objets d'élément bruts (avec le tag d'élément du framework) est bien plus rapide que la fabrique d'éléments du framework. - `new Array(n)` crée des tableaux à trous (« holey ») qui empoisonnent le type feedback ; évitez de pré-dimensionner les tableaux critiques en performance. Pièges du moteur et du langage : - Un modificateur `private` n'est pas autorisé sur une expression de classe anonyme assignée à une const. - Un import étoile réservé au type peut quand même déclencher la résolution de module du bundler, même si le système de types le supprime. Intégrité des démos et du contrôle qualité visuel (pour toute vitrine prétendant démontrer un comportement) : - Tolérance zéro pour les fausses démos. Chaque widget doit exercer le véritable chemin d'exécution qu'il prétend démontrer. Si une fonctionnalité ne peut pas s'exécuter sur une plateforme, laissez la cellule échouer bruyamment (mise en page cassée, avertissement, glyphe manquant) ; cet échec est la démo. Ne substituez jamais un mock qui imite la spécification, et ne codez jamais en dur une couleur de réussite/échec en guise de substitut au véritable chemin qui s'exécute. - Utilisez des composants omniplateformes sans branches spécifiques à une plateforme dans la vitrine ; les contournements liés aux écarts de plateforme appartiennent à la bibliothèque, pas à l'application. - Rendez la distinction fonctionnel/cassé perceptible d'un coup d'œil à distance via des différences macroscopiques (décalages de mise en page, inondations de couleur, présence/absence), et assurez-vous que chaque widget se lit correctement en mode clair comme en mode sombre.