Maison > Article > interface Web > Décodage de StyleX : le système de style de pointe de Meta
Chaque année en octobre, la plus grande conférence internationale React a lieu à Goa, en Inde. Oui, je parle de React India. Cette année (2024) a été encore plus spéciale pour moi puisque j'ai eu la chance de prendre la parole lors de cette magnifique conférence. Voici l'enregistrement de ma conférence si vous avez manqué de la regarder en direct. Si vous préférez lire plutôt que regarder des vidéos, alors ce blog est fait pour vous ! Allons-y.
StyleX est la nouvelle bibliothèque de styles évolutive de Meta qui est désormais utilisée comme système principal derrière des plateformes comme Facebook, Instagram et WhatsApp. Il aborde les problèmes rencontrés avec les approches CSS-in-JS, en particulier dans les applications React massives. En proposant une solution hybride qui allie les meilleures fonctionnalités du CSS atomique et du CSS statique, StyleX offre une alternative efficace, modulaire et évolutive.
Génération CSS atomique : StyleX utilise la génération CSS atomique, ce qui signifie qu'il crée de petites classes réutilisables pour chaque règle de style. Cette approche minimise non seulement la redondance dans le bundle CSS final, mais améliore également les performances en réduisant la taille globale des feuilles de style.
Déduplication CSS : En générant des identifiants de classe uniques pour chaque style, StyleX élimine efficacement les styles en double. Ce processus de déduplication garantit que chaque paire propriété-valeur n'est rendue qu'une seule fois, contribuant ainsi à une sortie CSS plus légère.
« Le dernier style appliqué gagne toujours ! » : StyleX suit une règle de style prévisible où le dernier style appliqué est prioritaire. Cette fonctionnalité simplifie le débogage et renforce la confiance des développeurs, car elle atténue les problèmes liés aux règles de style conflictuelles.
Optimisé pour React : Conçu spécifiquement pour les applications React, StyleX s'intègre parfaitement dans l'écosystème React. Il permet aux développeurs de définir des styles directement dans leurs composants, favorisant ainsi un flux de travail de développement plus cohérent.
Prise en charge de Flow et TypeScript : StyleX est écrit en "Flow" (créé par Meta) et fournit également une prise en charge robuste de TypeScript, permettant des API sécurisées pour les styles et les thèmes. Cette sécurité de type améliore la fiabilité et la maintenabilité du code, facilitant ainsi la gestion de scénarios de style complexes.
Style conditionnel flexible : avec StyleX, les développeurs peuvent appliquer des styles de manière conditionnelle en fonction des états des composants ou des accessoires. Cette flexibilité permet un style dynamique qui s'adapte aux interactions des utilisateurs ou aux changements d'état de l'application.
Style étendu : La fonction de style étendu de StyleX garantit que les styles sont appliqués uniquement aux composants auxquels ils sont destinés. Cela évite les effets secondaires involontaires et les problèmes de spécificité qui surviennent souvent dans les bases de code plus volumineuses.
Moins de calculs d'exécution : StyleX minimise les calculs d'exécution en regroupant tous les styles dans un fichier CSS statique au moment de la compilation. Cette optimisation conduit à des temps de rendu plus rapides et à des performances améliorées, en particulier dans les applications plus volumineuses.
Meilleure maintenabilité du code : en colocalisant les styles avec leurs composants respectifs et en utilisant des classes atomiques, StyleX favorise une meilleure maintenabilité du code. Les développeurs peuvent facilement comprendre et modifier les styles sans avoir à parcourir de longues feuilles de style.
Sortie CSS minimale : L'utilisation du CSS atomique entraîne une sortie CSS minimale, ce qui est particulièrement bénéfique pour les performances. À mesure que les projets augmentent en taille et en complexité, StyleX garantit que le bundle CSS reste gérable sans sacrifier la fonctionnalité.
Fonctionne bien pour les projets de toutes tailles : Bien que StyleX soit adapté aux projets de toutes tailles, il excelle vraiment dans les applications plus importantes. Son architecture est conçue pour gérer les complexités des besoins de style étendus sans compromettre les performances ou la maintenabilité.
Les exemples de code de cet article sont écrits en React, et nous travaillerons principalement avec deux composants, App.jsx et Button.jsx. Jetons un coup d'œil à la structure de base de ces composants avant d'ajouter des styles.
import Button from "./components/Button"; const App = () => { return ( <div> <h1>StyleX by Meta</h1> <Button text="Get Started" /> </div> ); }; export default App;
// Button.jsx import PropTypes from "prop-types"; const Button = ({ text }) => { return <button>{text}</button>; }; Button.propTypes = { text: PropTypes.string.isRequired, }; export default Button;
import PropTypes from "prop-types"; import * as stylex from "@stylexjs/stylex"; const styles = stylex.create({ base: { fontSize: 18, backgroundColor: "black", color: "white", }, }); const Button = ({ text }) => { return <button {...stylex.props(styles.base)}>{text}</button>; }; Button.propTypes = { text: PropTypes.string.isRequired, }; export default Button;
Pour utiliser ces styles, nous devons les importer depuis le package styleX, puis définir les styles à l'aide de la méthode stylex.create qui prend un objet comme paramètre. Nous pouvons ensuite utiliser la méthode stylex.props pour appliquer les styles au composant.
Dans cet exemple, base est le nom du style que nous voulons appliquer. Nous les appelons espaces de noms dans StyleX. Voici à quoi ressemble maintenant notre composant bouton.
import PropTypes from "prop-types"; import * as stylex from "@stylexjs/stylex"; const styles = stylex.create({ base: { fontSize: 18, backgroundColor: { default: "black", ":hover": "blue", }, color: "white", }, }); const Button = ({ text }) => { return <button {...stylex.props(styles.base)}>{text}</button>; }; Button.propTypes = { text: PropTypes.string.isRequired, }; export default Button;
Avec StyleX, c'est assez simple d'ajouter des styles aux pseudo-classes. Dans l’exemple précédent, backgroundColor était une chaîne. Ici, nous le convertissons en objet avec la valeur par défaut et une pseudo-classe.
import PropTypes from "prop-types"; import * as stylex from "@stylexjs/stylex"; const styles = stylex.create({ base: { fontSize: 18, backgroundColor: { default: "black", ":hover": "blue", }, color: "white", width: { default: "100px", "@media (max-width: 476px)": "100%", }, }, }); const Button = ({ text }) => { return <button {...stylex.props(styles.base)}>{text}</button>; }; Button.propTypes = { text: PropTypes.string.isRequired, }; export default Button;
Une chose que nous faisons différemment dans StyleX par rapport aux autres bibliothèques de styles est les requêtes multimédias. Ici, nous appliquons des requêtes multimédias à chaque espace de noms en fonction des exigences. Dans cet exemple, nous définissons la largeur du bouton sur 100 px pour les écrans plus grands et sur une largeur de 100 % pour les écrans plus petits ou les appareils mobiles.
Étendons l'exemple précédent pour voir comment nous pouvons créer différentes variantes de ce bouton.
const styles = stylex.create({ base: { fontSize: 18, backgroundColor: { default: "teal", ":hover": "blue", }, color: "white", width: { default: "100px", "@media (max-width: 476px)": "100%", }, }, highlighted: { backgroundColor: "orange", }, danger: { backgroundColor: "red", }, primary: { backgroundColor: "green", }, }); const Button = ({ text, isHighlighted, variant }) => { return ( <button {...stylex.props( styles.base, isHighlighted && styles.highlighted, // conditional styling styles[variant] )} > {text} </button> ); }; Button.propTypes = { text: PropTypes.string.isRequired, isHighlighted: PropTypes.bool, variant: PropTypes.oneOf(["danger", "primary"]), };
Ajoutons quelques espaces de noms supplémentaires à la méthode stylex.create et fournissons-leur différentes couleurs d'arrière-plan. De plus, nous acceptons 2 nouveaux accessoires dans notre composant Button. isHighlighted est un accessoire booléen que nous utilisons pour appliquer l'espace de noms en surbrillance. Et la variante est un accessoire que nous utilisons pour appliquer l'espace de noms principal, dangereux ou mis en surbrillance.
// App.jsx import Button from "./components/Button"; const App = () => { return ( <div> <h1>StyleX by Meta</h1> <div {...stylex.props(styles.main)}> <Button text="Base Button" /> <Button text="Highlighted Button" isHighlighted /> <Button text="Danger Button" isHighlighted variant="danger" /> <Button text="Primary Button" variant="primary" /> </div> </div> ); }; export default App;
Nous créons quelques copies supplémentaires du composant Button avec différents accessoires transmis. Voici à quoi ressemble notre application maintenant.
Maintenant, regardez de plus près le « bouton de danger ». Même si nous avons transmis isHighlighted comme vrai, l’espace de noms en surbrillance ne sera pas appliqué. La variante de danger est mentionnée en dernier lieu et sera donc appliquée. Ainsi, le bouton aura une couleur de fond rouge.
Nous pourrions remplacer les propriétés de style de ce composant Button directement depuis App.jsx.
import Button from "./components/Button"; const App = () => { return ( <div> <h1>StyleX by Meta</h1> <Button text="Get Started" /> </div> ); }; export default App;
Dans cet exemple, l'espace de noms de remplacement autorise actuellement toutes les propriétés. Cependant, StyleX nous donne la possibilité de limiter les propriétés pouvant être remplacées. Cette fonctionnalité devient particulièrement utile lors de l'utilisation de TypeScript.
// Button.jsx import PropTypes from "prop-types"; const Button = ({ text }) => { return <button>{text}</button>; }; Button.propTypes = { text: PropTypes.string.isRequired, }; export default Button;
Cette limitation garantit que seules les propriétés backgroundColor et color peuvent être remplacées.
Si vous faites défiler jusqu'à l'exemple de code précédent, vous verrez que nous avons ajouté le style margin : "1rem" à 3 espaces de noms différents - principal dans App.jsx, mis en évidence et primaire dans Button.jsx. Lorsque nous inspectons l'élément à l'aide de Devtools, nous pouvons voir que les différents composants (conteneur principal, bouton en surbrillance et bouton principal) sont attachés avec le même nom de classe et qu'il n'y a qu'une seule classe x42y017 qui contient la marge : style "1rem".
C'est ainsi que StyleX a considérablement réduit la taille de son bundle en employant des classes atomiques. Après avoir atteint un certain seuil, aucune nouvelle classe n'est générée ; au lieu de cela, ils réutilisent simplement les classes existantes.
Pouvoir remplacer les styles à un niveau granulaire est génial ! Cependant, tout système de conception donné doit prendre en charge les jetons de conception et les thèmes. C'est là que StyleX entre en jeu. La conception des API de thématisation dans StyleX est directement inspirée des API de contexte de React. Les variables sont définies avec des valeurs par défaut similaires à la façon dont les contextes React sont créés, et des thèmes peuvent être créés pour « fournir » différentes valeurs pour ces variables pour les sous-arborescences de l'interface utilisateur.
Nous pouvons créer des styles globaux en créant un fichier x.stylex.js. Assurez-vous de suivre cette convention de dénomination. Dans ce fichier, nous utilisons stylex.defineVars comme indiqué ci-dessous.
import PropTypes from "prop-types"; import * as stylex from "@stylexjs/stylex"; const styles = stylex.create({ base: { fontSize: 18, backgroundColor: "black", color: "white", }, }); const Button = ({ text }) => { return <button {...stylex.props(styles.base)}>{text}</button>; }; Button.propTypes = { text: PropTypes.string.isRequired, }; export default Button;
Nous faisons référence au thème préféré de l'utilisateur et le définissons sur une valeur constante - DARK. De plus, créons un nouveau thème en utilisant cette variable de couleurs.
import PropTypes from "prop-types"; import * as stylex from "@stylexjs/stylex"; const styles = stylex.create({ base: { fontSize: 18, backgroundColor: { default: "black", ":hover": "blue", }, color: "white", }, }); const Button = ({ text }) => { return <button {...stylex.props(styles.base)}>{text}</button>; }; Button.propTypes = { text: PropTypes.string.isRequired, }; export default Button;
Une fois le thème créé, il peut être utilisé comme n'importe quel autre style dans StyleX.
import PropTypes from "prop-types"; import * as stylex from "@stylexjs/stylex"; const styles = stylex.create({ base: { fontSize: 18, backgroundColor: { default: "black", ":hover": "blue", }, color: "white", width: { default: "100px", "@media (max-width: 476px)": "100%", }, }, }); const Button = ({ text }) => { return <button {...stylex.props(styles.base)}>{text}</button>; }; Button.propTypes = { text: PropTypes.string.isRequired, }; export default Button;
C'est ainsi que nous pouvons voir la même page avec myCustomTheme respectivement en mode clair et sombre.
Hourra ! Nous avons réussi à comprendre l'essentiel de notre travail avec StyleX. Merci d'avoir lu cet article. J'espère que cela a permis de bien comprendre ce qu'est StyleX, comment Meta l'a créé et comment l'utiliser. Veuillez partager vos réflexions/requêtes dans la section commentaires ou sur Twitter. Si ce blog vous intéresse, j'apprécierais que vous puissiez liker ce post (avec votre emoji préféré ?).
Paix ✌
Connectez-vous avec moi sur Topmate pour la préparation à l'entretien
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!