Gestaltete Komponenten in React: Die Abkehr von SCSS

CSS-Spezifikationskrieg

Da wir weiterhin unser monolithisches System in eine Microservices-basierte Architektur migrieren und durch die Micro-Frontend-Landschaft hier bei FloQast navigieren, ist es für mich immer schwieriger geworden, alle CSS zu verwalten, die unsere React-Komponenten stylen. Ich finde es zwar toll, dass wir mit Mikro-Frontends den Teamcode isolieren und unabhängige Implementierungen unterstützen können, aber ich habe auch festgestellt, dass sie die traditionell globale Natur der Stylesheet-Sprache verstärken.

Wenn ich zum Beispiel im Mikro-Frontend-Team A arbeite und das folgende CSS einfüge, wäre ich wahrscheinlich ziemlich enttäuscht über das Styling meiner Komponente.

// micro frontend team A
.icon {
    color: blue;
}

// micro frontend team B
.icon {
    color: white;
 }

Es kann zu Konflikten kommen, wenn verschiedene Mikro-Frontends versehentlich denselben Selektor oder Klassennamen verwenden. Da unsere Teams manchmal gleichzeitig an der gleichen Seite arbeiten, kann es eine Herausforderung sein, sicherzustellen, dass jedes Team seine Stile unabhängig voneinander schreibt. Dies gilt insbesondere dann, wenn der Code auf verschiedene Repositories aufgeteilt ist und verschiedene Teams CSS zu unterschiedlichen Zeiten aktualisieren können.

Ich achte besonders darauf, dass sich neue CSS-Regeln nicht fälschlicherweise auf andere Komponenten in der App auswirken. CSS bietet zwar einen Grad an Wiederverwendbarkeit, der es mir ermöglicht, redundante Stildeklarationen zu vermeiden, aber dieser Aspekt kann auch Abhängigkeiten zwischen HTML-Elementen und CSS-Regeln schaffen, typischerweise auf folgende Weise:

1. Mehrere Selektoren werden gruppiert, um verschiedene HTML-Elemente anzuvisieren und zu gestalten.

.percentage-number, .percentage-sign { 
  font-size: 40px; 
  line-height: 1; 
}

2. Mehrere Klassennamen werden auf dieselben HTML-Elemente angewendet, so dass sie von mehreren CSS-Regeln erfasst werden.

.success { color: green; } 
.status-icon { font-size: 48px; } 

<div className="success status-icon" />

Es fällt mir schwer, den Überblick über diese Abhängigkeiten zu behalten, vor allem, wenn andere Entwickler am Code arbeiten. Ich kann vergessen, welche Regeln tatsächlich aktualisiert oder gelöscht werden müssen.

Gibt es also eine andere Möglichkeit, Stylesheets zu organisieren?

Entkopplung monolithischer Stylesheets

Um unser GSS besser verwalten zu können, haben wir vor kurzem styled-componentseine CSS-In-JS-Bibliothek, die es uns ermöglicht, CSS ohne unerwartete Seiteneffekte zu verändern, und uns die Gewissheit gibt, dass sich unsere Mikro-Frontends wie erwartet verhalten, wenn sie zusammengefügt werden.

Styled Components bringen Ihre Stile in das Zeitalter der Komponenten. Wenn Sie schon einmal mit React gearbeitet haben, wissen Sie vielleicht, dass es die beste Praxis ist, Komponenten zu erstellen, die völlig unabhängig voneinander sind, und einzelne Klassennamen für das Styling zu verwenden. Styled Components helfen Ihnen, diese Best Practices durchzusetzen, indem sie eine Eins-zu-Eins-Beziehung zwischen einem HTML-Element und seinem CSS durch eindeutige Klassennamen für Ihre Stile fördern. Außerdem schließen sie die Lücke zwischen Komponenten und Styling, indem sie Ihnen die Möglichkeit geben, Komponenten auf eine wiederverwendbare Weise zu stylen.

Mit Styled Components müssen Sie sich nicht um die Verwaltung von Stylesheets kümmern und können das Javascript-Ökosystem nutzen, indem Sie Ihr CSS direkt in Ihre Javascript-Dateien schreiben.

Verwendung gestalteter Komponenten

Gestaltete Komponenten nutzen die Leistungsfähigkeit von getaggten Vorlagen zur Gestaltung von Komponenten.

"Es entfernt das Mapping zwischen Komponenten und Styles. Das bedeutet, dass Sie beim Definieren Ihrer Stile tatsächlich eine normale React-Komponente erstellen, der Ihre Stile zugeordnet sind." -Styled Components

Lassen Sie uns einen Blick auf die Magie werfen:

import styled from 'styled-components';

// Styled Component named StyledLabel
const StyledLabel = styled.label`
    color: gray;
    font-weight: 700;
    font-size: 12px;
    text-transform: uppercase;
`;

const Component = () => {
  // Use it like any other component
  return <StyledLabel>Search</StyledLabel>;
}

In diesem Beispiel ist StyledLabel eine Styled Component, die ein HTML-Label mit den zugehörigen Stilen wiedergibt. Die styled Methode wird dann das Styling von Javascript in tatsächliches CSS umgewandelt.

Hier sehen Sie, wie die ursprüngliche Komponente und das CSS aussahen:

label { 
  color: gray; 
  font-weight: 700; 
  font-size: 12px; 
  text-transform: uppercase; 
} 

<label>Search</label>

Wenn Styled Components das StyledLabel erstellt, wird ein Hashing-Algorithmus verwendet, um einen eindeutigen Bezeichner zu erzeugen. Dadurch wird verhindert, dass sich Klassennamen überschneiden, und Sie müssen sich nicht selbst einen ausdenken.

<label class="jewpRe bkIsBc">Search</label>

Sie können auch Ihre eigenen benutzerdefinierten Komponenten transformieren. Vergewissern Sie sich nur, dass Sie dem zugrunde liegenden DOM-Element einen className-Prop übergeben.

const SearchBar = ({ className, value, onChange, placeholder}) => {
    return {
        <TextInput
            className={className}
            value={value}
            onChange={e => onChange(e.target.value)}
            placeholder={placeholder}
        />
    };
};

const StyledSearchBar = styled(SearchBar)`
    line-height: 18px;
    font-size: 18px;
    margin: 1px -5px;
`;

Wenn Sie nun CSS hinzufügen oder ändern, müssen Sie sich keine Sorgen mehr machen, dass Ihre Stile unvorhersehbar in andere Teile der Anwendung übergehen. Wenn Sie eine Komponente löschen, werden auch alle Stile zusammen mit ihr gelöscht, sodass Sie keinen toten Code mehr haben und nicht mehr nach Klassennamen suchen müssen.

Andere Leistungen

Neben dem Scoping von Stilen und der Verbesserung der Entwicklererfahrung bieten Styled Components auch Folgendes:

  • Automatisches kritisches CSS: Injizieren Sie nur die kritischen CSS, die an gerenderte Komponenten gebunden sind, um unnötiges Laden von Code zu vermeiden.
  • Automatische Hersteller-Präfixe: Wenden Sie Herstellerpräfixe auf CSS-Bestimmungen an, damit Sie das nicht tun müssen.
  • Dynamisches Styling: Übergeben Sie Requisiten auf die gleiche Weise, wie Sie es bei regulären React-Komponenten tun würden.
  • Themen: Einfaches Definieren eines gemeinsamen Stylings. Die Context-APIs von React bieten die Möglichkeit, Requisiten an alle gestylten Komponenten innerhalb der ThemeProvider Umschlag.

Beeinträchtigungen

In Bezug auf die Leistung machen die Styled Components Ihre .js bündelt etwas mehr Gewicht und fügt Ihrer Anwendung eine zusätzliche Schicht hinzu. Im Gegenzug hilft Ihnen die Bibliothek jedoch, die Anzahl der Netzwerkanfragen für .css Dateien, da nur die für eine Seite erforderlichen Stile geladen werden.

Schlussfolgerung

CSS-In-JS-Bibliotheken werden in der modernen Frontend-Entwicklung wahrscheinlich weiter an Bedeutung gewinnen. Insbesondere mit der Popularität von komponentenbasierten Bibliotheken/Frameworks wie React. Wenn Ihr Team derzeit wiederverwendbare Komponenten einsetzt, können CSS-In-JS-Bibliotheken einen Blick wert sein. Sie können Ihnen helfen, einige häufige CSS-Frustsituationen zu umgehen.

Zusätzliche Ressourcen

Stephanie Chiu

Software-Ingenieur bei FloQast. Zu seinen Hobbys gehören das Anschauen von Fernsehsendungen und Reisen in neue Städte (und das Essen dort).



Zurück zu Blog