Audit de composant
Auditez les composants de code existants pour les décisions architecturales spécifiques à Webflow. Cette skill se concentre sur la qualité de l'intégration des composants avec Webflow Designer, pas sur les meilleures pratiques React génériques.
Quand utiliser cette skill
À utiliser quand :
- L'utilisateur souhaite améliorer le fonctionnement de ses composants dans Webflow Designer
- Il faut vérifier si les bonnes choses sont exposées comme props ou codées en dur
- Il faut vérifier si les patterns de gestion d'état sont compatibles avec Webflow
- Il faut chercher des opportunités de rendre les composants plus conviviaux pour les designers
- Un composant n'affiche pas ou ne se comporte pas correctement dans Webflow
À NE PAS utiliser quand :
- Valider avant le déploiement (utiliser pre-deploy-check à la place)
- Créer de nouveaux composants (utiliser component-scaffold à la place)
- Convertir un composant React (utiliser convert-component à la place)
- Faire une revue générique de qualité de code (utiliser un linter)
Philosophie centrale
Cet audit répond à trois questions :
- Contrôle du designer : Les bonnes choses sont-elles exposées comme props pour que les designers les personnalisent ?
- Compatibilité Webflow : Le composant fonctionne-t-il dans les contraintes de Webflow (Shadow DOM, SSR, racines React isolées) ?
- Architecture du composant : Est-ce le bon niveau de granularité, ou faudrait-il le diviser/combiner ?
Instructions
Phase 1 : Découverte
-
Trouver tous les composants :
- Localiser webflow.json
- Trouver tous les fichiers .webflow.tsx
- Lire les composants React correspondants
-
Comprendre l'intention : Demander à l'utilisateur à quoi servent les composants et ses préoccupations spécifiques
Phase 2 : Analyse
Pour chaque composant, analysez ces domaines spécifiques à Webflow :
A. Analyse d'exposition des props
Objectif : Identifier ce que les designers DEVRAIENT pouvoir contrôler mais ne peuvent pas actuellement.
| À chercher | Recommandation |
|---|---|
| Chaînes de texte codées en dur | Exposer en tant que props.Text() |
| Texte que les designers devraient modifier sur le canvas | Exposer en tant que props.RichText() |
| Valeurs codées en dur d'un ensemble d'options fixe | Exposer en tant que props.Variant({ options: [...] }) |
| URLs d'image codées en dur | Exposer en tant que props.Image() |
| URLs de lien codées en dur | Exposer en tant que props.Link() |
Attributs HTML id codés en dur |
Exposer en tant que props.Id() |
| Rendu conditionnel avec booléen | Exposer en tant que props.Boolean() ou props.Visibility() |
| État interne qui affecte l'apparence | Envisager d'exposer la valeur initiale comme prop |
children n'utilisant pas Slot |
Convertir en props.Slot() |
Alias :
props.String=props.Text,props.Children=props.Slot. Traiter ces comme équivalents lors de l'audit.
Questions à poser :
- « Qu'est-ce qu'un designer voudrait changer ? »
- « Qu'est-ce qui nécessite une modification du code qui ne devrait pas ? »
B. Architecture de gestion d'état
Objectif : Identifier les patterns qui ne fonctionneront pas dans Webflow.
| Anti-pattern | Pourquoi ça échoue | Alternative |
|---|---|---|
| React Context pour l'état entre composants | Chaque composant a une racine React isolée | Utiliser nano stores, événements personnalisés ou paramètres URL |
| Prop drilling via des Slots | Les enfants Slot sont des applications React séparées | Utiliser nano stores ou événements personnalisés |
| État partagé via variables au niveau du module | Peut causer des problèmes SSR | Utiliser le stockage du navigateur ou nano stores |
| Écouteurs d'événements globaux sans nettoyage | Fuites mémoire, problèmes SSR | Utiliser useEffect avec cleanup |
Recommandations de refactorisation :
- Si les composants doivent communiquer → suggérer le pattern d'état entre composants
- Si Context est utilisé uniquement en interne → c'est OK, le documenter
- Si les composants sont étroitement couplés → suggérer la décomposition
C. Opportunités de Slot
Objectif : Identifier le contenu codé en dur qui devrait être contrôlé par le designer.
| Pattern actuel | Meilleur pattern |
|---|---|
| Bouton codé en dur à l'intérieur de la carte | Slot pour la zone d'actions |
| Composant icône codé en dur | Slot ou prop Image |
| Structure d'en-tête/pied de page fixe | Slots pour en-tête et pied de page |
| Éléments de liste codés en dur | Considérer si cela devrait être plusieurs composants |
Quand NE PAS utiliser les Slots :
- Quand le contenu a des exigences comportementales spécifiques
- Quand le contenu doit interagir avec l'état du composant
- Quand la structure est vraiment fixe et non personnalisable
D. Compatibilité Shadow DOM
Objectif : S'assurer que les styles fonctionnent en isolement.
| Problème | Détection | Correctif |
|---|---|---|
| Utilisation de classes CSS site/global | Noms de classe comme .container, .btn |
Utiliser CSS Modules ou des styles limités au composant |
| CSS-in-JS non configuré | styled-components/Emotion sans décorateur | Ajouter globals.ts avec styledComponentsShadowDomDecorator (styled-components) ou emotionShadowDomDecorator (Emotion/MUI) |
| Imports de style manquants | Styles définis mais non importés dans .webflow.tsx | Ajouter une déclaration import |
| Reliance sur les styles hérités | S'attendre à ce que les styles parents se propagent | Utiliser des styles explicites ou des variables CSS |
| Besoin de sélecteurs de balise (h1, p, etc.) | Les balises ne sont pas stylisées dans Shadow DOM | Activer applyTagSelectors: true dans les options du composant |
Note SSR : Quand vous utilisez styled-components ou Emotion, vous devez également configurer le rendu serveur dans
webflow.jsonpour que SSR fonctionne correctement :
- styled-components:
"library": { "renderer": { "server": "@webflow/styled-components-utils/server" } }- Emotion:
"library": { "renderer": { "server": "@webflow/emotion-utils/server" } }
E. Sécurité SSR
Objectif : Identifier le code spécifique au navigateur qui s'exécute lors du rendu.
| Pattern | Problème | Solution |
|---|---|---|
window.innerWidth dans le rendu |
Erreur SSR | Utiliser useEffect ou définir ssr: false |
document.getElementById dans le rendu |
Erreur SSR | Utiliser useEffect ou refs |
localStorage.getItem en dehors de useEffect |
Erreur SSR | Wrapper dans useEffect avec useState |
| Bibliothèque tierce nécessitant window | Erreur SSR | Import dynamique ou ssr: false |
F. Granularité du composant
Objectif : Déterminer si le composant est au bon niveau d'abstraction.
Signes qu'un composant devrait être DIVISÉ :
- Trop de props (>10) rendant l'UI du Designer encombrée
- Plusieurs sections distinctes qui pourraient être indépendantes
- Les designers veulent utiliser les parties séparément
- Le composant traite plusieurs préoccupations sans lien
Signes que les composants devraient être COMBINÉS :
- Toujours utilisés ensemble
- État étroitement couplé qui est maladroit à synchroniser
- Petits composants sans utilisation autonome
Phase 3 : Rapport
Générez un rapport exploitable avec :
- Résumé : Aperçu rapide des conclusions
- Par composant : Problèmes spécifiques et recommandations pour chacun
- Recommandations architecturales : Préoccupations transversales
- Actions prioritaires : Quoi corriger en premier
Liste de contrôle d'audit
Contrôle du designer (le plus important pour Webflow)
| Vérification | Question |
|---|---|
| Complétude des props | Les designers peuvent-ils personnaliser tout ce qu'ils voudraient ? |
| Types de props | Les bons types de props Webflow sont-ils utilisés ? |
| Valeurs par défaut | Les props ont-elles des valeurs par défaut sensées ? |
| Nommage des props | Les noms sont-ils clairs pour les non-développeurs ? |
| Utilisation de Slot | Le contenu imbriqué est-il géré via les Slots ? |
| Props de visibilité | Les sections peuvent-elles être affichées/masquées ? |
Compatibilité Webflow
| Vérification | Question |
|---|---|
| Sécurité SSR | Le composant se rend-il sans APIs navigateur ? |
| Isolement des styles | Les styles fonctionnent-ils dans Shadow DOM ? |
| Indépendance d'état | Le composant fonctionne-t-il sans Context du parent ? |
| Pas de props fonction | Y a-t-il des props callback qui ne fonctionneront pas ? |
Architecture
| Vérification | Question |
|---|---|
| Responsabilité unique | Le composant fait-il une seule chose bien ? |
| Granularité appropriée | Est-ce la bonne taille pour l'utilisation du Designer ? |
| État entre composants | Si nécessaire, est-il implémenté correctement ? |
Exemple
Prompt utilisateur :
Audit my ProductCard component
Réponse :
## Audit : ProductCard
### Vue d'ensemble du composant
```typescript
// Props actuelles
props: {
title: props.Text(),
price: props.Number(),
imageUrl: props.Text() // ⚠️ Devrait être Image
}
A. Analyse d'exposition des props
| Constatation | Sévérité | Recommandation |
|---|---|---|
imageUrl est Text, pas Image |
Attention | Changer en props.Image() pour une gestion appropriée des assets |
| Le texte du bouton « Add to Cart » est codé en dur | Suggestion | Exposer en tant que prop : addToCartText: props.Text() |
| Le badge de vente est rendu conditionnellement mais non contrôlable | Suggestion | Ajouter showSaleBadge: props.Boolean() |
| La couleur du badge est codée en dur en rouge | Suggestion | Ajouter badgeVariant: props.Variant({ options: ["sale", "new", "featured"] }) |
Contenu codé en dur trouvé :
// Ligne 24 - codé en dur, devrait être une prop
<button>Add to Cart</button>
// Ligne 18 - codé en dur, devrait être une prop ou supprimé
{onSale && <span className="badge">SALE</span>}
Props recommandés à ajouter :
props: {
// ...existant
addToCartLabel: props.Text({
name: "Button Label",
defaultValue: "Add to Cart"
}),
showBadge: props.Boolean({
name: "Show Badge",
defaultValue: false
}),
badgeType: props.Variant({
name: "Badge Type",
options: ["sale", "new", "featured"],
defaultValue: "sale"
})
}
B. Gestion d'état
| Constatation | Sévérité |
|---|---|
Utilise localStorage pour le nombre d'articles du panier |
Attention |
| Aucune dépendance React Context | OK |
Problème : localStorage dans le rendu
// Ligne 8 - cassera SSR
const cartCount = localStorage.getItem('cart');
Correctif :
const [cartCount, setCartCount] = useState(0);
useEffect(() => {
setCartCount(parseInt(localStorage.getItem('cart') || '0'));
}, []);
C. Opportunités de Slot
| Actuel | Recommandation |
|---|---|
| Bouton codé en dur | Considérer : actions: props.Slot() pour les CTA flexibles |
Si les designers doivent mettre un contenu différent (bouton, lien, élément personnalisé) dans la zone d'action :
props: {
actions: props.Slot({
name: "Actions"
})
}
// Composant
<div className={styles.actions}>
{actions}
</div>
Cependant, si le comportement du bouton est lié à la logique du panier, le garder codé en dur.
D. Compatibilité Shadow DOM
| Vérification | Statut |
|---|---|
| Styles importés dans .webflow.tsx | ✅ OK |
| CSS Modules utilisés | ✅ OK |
| Aucune référence de classe global | ✅ OK |
E. Sécurité SSR
| Vérification | Statut |
|---|---|
| Utilisation de window | ✅ Aucune |
| Utilisation de document | ✅ Aucune |
| Utilisation de localStorage | ⚠️ Besoin de garde (voir le correctif ci-dessus) |
F. Granularité du composant
Taille actuelle : 4 props (sera 7 après recommandations) Verdict : Bonne granularité - objectif unique, props gérables
Résumé
| Catégorie | Statut |
|---|---|
| Contrôle du designer | ⚠️ Besoin de travail - 4 éléments codés en dur trouvés |
| Gestion d'état | ⚠️ localStorage doit avoir une garde SSR |
| Shadow DOM | ✅ OK |
| Sécurité SSR | ⚠️ Un problème |
| Granularité | ✅ OK |
Actions prioritaires :
- Corriger le problème SSR de localStorage (bloque le déploiement)
- Changer imageUrl de prop Text à Image
- Exposer les contrôles de badge comme props
- Envisager d'exposer le label du bouton
Directives
Ce que cet audit NE vérifie PAS
Ceci n'est pas un audit générique de qualité de code. Ignorer :
- Les patterns de performance React génériques (laisser les utilisateurs utiliser React DevTools)
- L'accessibilité générique (laisser les utilisateurs utiliser axe ou similaire)
- Le formatage du code (laisser les utilisateurs utiliser Prettier/ESLint)
- Les meilleures pratiques TypeScript génériques
Se concentrer uniquement sur les préoccupations spécifiques à Webflow.
Heuristiques d'exposition des props
Devrait être une prop :
- Tout texte visible dans l'UI
- Toute image ou média
- Toute couleur ou taille qui peut varier
- Tout booléen qui contrôle la visibilité
- Toute valeur qui change par utilisation
Ne devrait PAS être une prop :
- Détails d'implémentation interne
- État qui change lors de l'interaction
- Valeurs dérivées d'autres props
- Timing/easing d'animation (sauf si explicitement personnalisable)
Quand recommander les Slots par rapport aux props
Utiliser Slot quand :
- Le designer veut mettre des éléments Webflow arbitraires à l'intérieur
- La structure du contenu est flexible
- Le contenu imbriqué n'a pas besoin d'interagir avec l'état du composant
Utiliser des props quand :
- Le contenu est simple (texte, image, lien)
- Le composant doit traiter/transformer le contenu
- Une structure spécifique est requise
Recommandations de pattern d'état
Si les composants doivent partager l'état, recommander dans cet ordre :
- Paramètres URL - si l'état doit être partageable/marquable
- Nano stores - pour la synchronisation en temps réel entre composants
- Événements personnalisés - pour la communication sans retour
- Stockage du navigateur - pour la persistence entre sessions