So können Sie Ihre React-Komponenten mit Storybook besser verwalten

Überblick: Ich war sehr aufgeregt, als ich letzte Woche die Veröffentlichungsankündigung für Storybook 3.4 gelesen habe, und habe beschlossen, einen Artikel über Storybook zu schreiben. In diesem Artikel werden wir uns ansehen, wie wir mit Storybook ein besseres React-Projekt erstellen und mit einigen von Storybook angebotenen Addons spielen können. Außerdem werden wir Storyshots in unseren Workflow integrieren, um sowohl strukturelle als auch Image-Snapshots für eine bessere Regression der Benutzeroberfläche zu erhalten Prüfung. Demo

React + Storybook = Love - Foto mit freundlicher Genehmigung von Leah Kelley aus Pexels mit wenigen eigenen Bildbearbeitungen durch Programmierer.

Wenn Sie an einem React-Projekt arbeiten, definieren Sie in der Regel wiederverwendbare Teile Ihrer Anwendung in Form von Komponenten. Es kann vorkommen, dass die Größe Ihres React-Projekts so schnell abnimmt und außer Kontrolle gerät, dass Sie oder Ihre Teammitglieder nicht einmal wissen, wie eine Komponente aussieht, oder dass Ihr Teammitglied eine andere Button-Komponente erstellt hat, nur weil er / sie weiß nicht, ob es schon mal jemand erstellt hat. Dies sind die offensichtlichen Anzeichen dafür, dass Sie Storybook in Ihrem Projekt benötigen.

Also, was ist Storybook und warum sollten wir es verwenden? Nach der Definition von Storybook ist es eine UI-Entwicklungsumgebung, die Sie gerne verwenden werden (ich liebe es, ich denke, Sie sollten es auch!). Mit Storybook können Sie Komponenten innerhalb eines Projekts durchsuchen, an seinem Status basteln und ihn interaktiv entwickeln und testen. Es wird außerhalb des Anwendungsbereichs ausgeführt, sodass Sie Ihre Komponenten entwickeln können, ohne sich um Abhängigkeiten zwischen Anwendungen kümmern zu müssen. Wenn Ihr Designer also die Farbe einer Schaltfläche von Rot auf Blau ändern möchte, müssen Sie sich nicht um einige Fehler in Ihren Apps sorgen, weil Sie gestern Abend betrunken waren , er / sie könnte einfach das Storybook ausführen und die Komponente direkt ändern.

Storybook unterstützte mehrere Front-End-Frameworks von Anfang an, wichtige Front-End-Frameworks wie React, React Native, Angular und Vue (endlich einigten wir uns auf etwas, Angular- und Vue-Leute!) Werden spätestens seit einiger Zeit unterstützt Release fügten sie auch Träger für Polymer.

Storybook installieren

Der erste offensichtliche Schritt, um mit Storybook zu arbeiten, ist die Installation. Um den Einrichtungsprozess zu vereinfachen, hat das Storybook-Team ein CLI-Tool zur Integration von Storybook in ein vorhandenes Projekt erstellt. Sie können dieses Tool global mit dem folgenden Befehl installieren:

garn global add @ storybook / cli

oder wenn du lieber npm anstelle von garn verwendest:

npm i -g @ storybook / cli

Gehen Sie nach Abschluss des Installationsschritts zu Ihrem React-Projekt und führen Sie einfach getstorybook aus:

cd mein-reaktions-projekt
getstorybook

Die Storybook-CLI ermittelt dann auf clevere Weise die Architektur Ihres Projekts und installiert Storybook entsprechend den Anforderungen des Projekts. Wenn Sie also eine Create-React-App oder ein einfaches Webpack verwenden, müssen Sie Storybook nur so installieren Einfacher Einzelbefehl!

Als Nächstes möchten Sie sicherstellen, dass Storybook ordnungsgemäß installiert wurde. Dazu können Sie einfach Folgendes ausführen:

Fadenlauf-Märchenbuch

Wenn Sie zu http: // localhost: 9009 / navigieren, sehen Sie Folgendes, wenn Storybook ordnungsgemäß installiert wurde:

Storybook-Begrüßungsbildschirm, Glückwunsch, du bist der Auserwählte!

Anpassen der Storybook-Installation

Die gesamte Storybook-Konfiguration für Ihr Projekt befindet sich im Verzeichnis .storybook. Sie finden dieses Verzeichnis im Stammverzeichnis Ihres Projekts. Es gibt verschiedene Dateien, mit denen Sie Ihre Storybook-Installation anpassen können:

  • config.js - In dieser Datei können Sie die Konfiguration für Ihre Storybook-Installation anpassen.
  • addons.js - Mit dieser Datei können Sie Storybook-Addons registrieren.
  • preview-head.html - Sie können diese Datei verwenden, wenn Sie Tags in Ihr Storybook-Head-Tag einfügen möchten. Diese Datei kann hilfreich sein, wenn Sie externe Skripte, CSS-Dateien oder möglicherweise Schriftarten haben, die in Ihr Storybook eingefügt und nicht gebündelt werden müssen App.
  • webpack.config.js - Storybook verwendet standardmäßig automatisch die eigene Webpack-Konfiguration. Sie können die Standardkonfiguration des Webpacks mit dieser Datei erweitern, wenn Sie beispielsweise einen anderen Webpack-Loader für Ihr Projekt benötigen. Weitere Informationen zum Anpassen der Webpack-Konfiguration für Storybook finden Sie hier.
  • .babelrc - Standardmäßig lädt Storybook .babelrc aus dem Stammverzeichnis des Projekts. Wenn Sie einige Regeln für die Storybook-Umgebung ausschließen müssen, können Sie diese Datei bereitstellen, damit nur Regeln aus dieser Datei von Storybook geladen werden.

Aus persönlichen Gründen möchte ich, dass meine Story-Dateien sich neben den zugehörigen React-Komponentendateien befinden. Anstatt also nur ein einziges großes Story- / Verzeichnis zu haben, würde ich es folgendermaßen ausdrücken:

Komponenten /
    Taste/
       button.js
       button.stories.js
       button.css

Dazu müssen wir die loadStories-Funktion von config.j folgendermaßen ändern:

dazu:

Im obigen Beispiel haben wir den require.context von Webpack verwendet, um alle Dateien zu laden, die mit .stories.js enden. Wenn wir also eine neue Story-Datei hinzufügen, müssen wir sie nicht immer wieder angeben.

Schreiben Sie unsere erste Geschichte

Genug mit der Konfiguration, schreiben wir unsere erste Geschichte. In diesem Beispiel verwenden wir das Projekt aus meinem vorherigen Beitrag zum Schreiben von wiederverwendbarem Redux wie ein Boss. Der Grund, warum wir dieses Projekt verwenden, ist, besser zu demonstrieren, wie wir unsere UI-Komponente entwickeln können, ohne die bereits vorhandenen Geschäftslogiken zu berühren.

In diesem Beispiel schreiben wir eine Story für die Komponente "Kurs-Widget":

Die Kurs Widget Komponente

Die Kurs-Widget-Komponente ist für die Anzeige einer Liste von Kursen verantwortlich, die Benutzer auf unserer React News-Website anmelden können. Sie empfängt eine Reihe von Kursen und rendert sie.

Um eine Story zu erstellen, importieren wir einfach storiesOf aus @ storybook / react und fügen dann jeden unserer Story-Einträge wie im obigen Beispiel hinzu. Anschließend können Sie Ihr Storybook erneut ausführen und die Story sofort anzeigen:

Der Eintrag Kurse Widget Stories.Der Eintrag Kurs-Widget-Artikelgeschichten.

Um unsere Kurs-Widget-Komponente besser dokumentieren zu können, möchten wir allen, die diese Geschichte sehen, mitteilen, ob auf unseren Registrierungsbutton tatsächlich geklickt werden kann. Momentan passiert nichts, wenn Sie auf die Schaltfläche "Registrieren" klicken. Dies wird mit unserem ersten Addon geändert.

Installation unseres ersten Addons

Das Installieren von Addons für Storybook ist ebenfalls recht einfach. Für unser erstes Addon fügen wir ein Aktions-Addon hinzu. Dazu müssen wir es zuerst mit Garn installieren:

Garn hinzufügen --dev @ storybook / Addon-Aktionen

oder npm:

npm i -D @ storybook / addon-aktionen

Normalerweise möchten wir Storybook-Addons in devDependencies installieren, damit wir unsere Produktionsabhängigkeiten nicht verschmutzen, schließlich benötigen wir sie in unseren Produktions-Builds nicht. Nachdem wir die Addons installiert haben, müssen wir sie registrieren, damit Storybook sie später verwenden kann. Um unsere Addons zu registrieren, können wir sie einfach in unsere Datei addons.js im Verzeichnis .storybook importieren:

Anschließend können wir die Aktionen in unserer Datei courses-widget.stories.js definieren:

Wenn Sie jetzt auf die Schaltfläche "Registrieren" klicken, wird eine Aktion im Aktionsprotokoll protokolliert:

Der Action Logger-Ausgang

Wenn Sie auf die Anmeldeschaltfläche klicken und diese nicht reagiert, wissen Sie, dass ein Fehler aufgetreten ist, und es wird erklärt, warum sich diese begeisterten Köpfe in den letzten Tagen nicht für unsere Kurse anmelden können.

Generieren Sie mit Info Addon eine einfache Dokumentation

Wir haben eine Komponentenbibliothek mit Storybook erstellt. Nun, wir können mit info addon automatisch eine Dokumentation generieren:

Beispieldokumentation aus unserem Kurs-Widget mit Info-Addon

Zuerst installieren Sie es mit:

Garn hinzufügen --dev @ storybook / addon-info

Um unseren Anforderungen besser gerecht zu werden, führen wir einige Setups in config.js durch:

Da sich das Info-Addon direkt in das Reagieren-Dokument integrieren lässt, um eine Tabelle mit Requisitentypen zu erstellen, können wir Requisitentypen verwenden. Wenn Sie fortgeschrittenere Anwendungsfälle wünschen, können Sie Flow verwenden Daher kann es während der gesamten Lebensdauer Ihrer Anwendung nur für einen Datentyp verwendet werden. Ich könnte etwas über statische Typenkontrolle schreiben und warum sie hier so toll sind, aber lassen Sie es uns für einen weiteren Tag behalten. Jetzt müssen Sie Flow nur noch mit den folgenden Befehlen installieren:

Garn hinzufügen --dev Flow-Bin
Fadenlauf Fließbeginn

Anschließend müssen wir die Flusstypen in unserer Kurs-Widget-Komponente definieren:

Anschließend fügen wir in unserer Story-Datei für die Komponente "Kurs-Widget" einen neuen Story-Eintrag hinzu, der mit der Funktion "Info" umschlossen ist:

Schnappschusstest mit Storyshots

Mit Storyshots können wir automatisch Snapshot-Tests mit Storybook hinzufügen. Bei Storyshots müssen wir in unserem Testframework keine weiteren Schnappschuss-Tests wie Jest angeben, sondern verwenden einfach unsere zuvor erstellten Storys. Um Storyshots zu verwenden, installieren wir es zunächst mit:

Garn hinzufügen --dev @ storybook / Addon-Storyshots

Wir können dann einfach eine neue Testdatei in unser ./src Verzeichnis einfügen, um Storyshots zu initialisieren:

Wenn wir unsere Testsuiten mit einem Garnlauf-Test ausführen, können wir unsere Schnappschüsse in jedem Verzeichnis unserer Komponenten anzeigen.

Der Schnappschuss wurde erfolgreich in unserem Komponentenverzeichnis für das Kurs-Widget erstellt

Wenn Sie nun die Struktur Ihrer Komponente ändern, erhalten Sie eine Warnung, dass sich etwas geändert hat:

Etwas hatte sich geändert, ist es das was du willst oder bist du nur bruh betrunken?

Wenn diese Änderungen erwartet werden, können Sie einfach u drücken, um fehlgeschlagene Snapshots zu aktualisieren, oder i drücken, um die fehlgeschlagenen Snapshots interaktiv zu aktualisieren.

Mit strukturellen Snapshot-Tests können wir vergleichen, wie die Struktur einer Komponente aussieht, und darauf aufbauend Regressionstests durchführen. Es können jedoch keine Änderungen erfasst werden, die möglicherweise visuell auftreten. Wenn Sie oder Ihre Teammitglieder beispielsweise einige CSS-Regeln geändert und die Darstellung der Komponente geändert haben, können Sie diese Regression nicht nur mit einem strukturellen Regressionstest erfassen.

Zum Glück konnten wir in Storybook 3.4 unsere Storys nicht nur zum Testen von strukturellen Schnappschüssen verwenden, sondern auch zum Testen visueller Schnappschüsse. Dazu können wir einfach eine andere Storyshots-Suite initialisieren:

Was Storyshots beim Testen von Bildschnappschüssen tun, ist im Grunde, mit einem kopflosen Browser (Puppenspieler) zu einer bestimmten Storybook-URL zu navigieren, Screenshots von jeder unserer Geschichten aufzunehmen und sie als Bilder zu speichern, um später visuelle Regressionstests durchzuführen. Visuelle Regressionstests können dann mit Hilfe eines Scherz-Bild-Schnappschusses durchgeführt werden. Damit unser Image-Snapshot-Test ausgeführt werden kann, müssen wir unsere Storybook-Instanz zuerst mit dem Garn-Storybook starten oder eine statische Instanz mit dem Garn-Build-Storybook erstellen.

Anstatt jedes Mal zwei Skripte auszuführen, wenn wir unsere Testsuiten ausführen möchten, können wir npm-run-all verwenden, um alles auf einmal auszuführen, und wait-port, um zu warten, bis das Storybook bereit ist, die Anforderung zu verarbeiten. Installieren wir npm-run-all und wait-port mit:

Garn hinzufügen --dev npm-run-all Wait-Port

Dann können wir in package.json ein neues Skript erstellen, um es auszuführen:

Jetzt können wir unsere Tests mit Garntest durchführen: ansehen. Wenn Sie die Tests erneut ausführen, werden Sie feststellen, dass Image-Snapshots erfolgreich im Verzeichnis __image_snapshots__ generiert wurden:

Image-Snapshot erfolgreich generiert.

Wenn Sie einige CSS-Regeln ändern, gibt Jest eine Warnung aus, dass die visuelle Regression fehlgeschlagen ist, und fragt, ob dies erwartet wurde oder nicht:

Jetzt hat sich das Aussehen geändert, wird es erwartet? Bitte überprüfen Sie die Bilddatei für weitere Informationen

Wir können dann den Unterschied in der Diff-Datei überprüfen, die generiert wurde:

Hoppla! Wir haben versehentlich die Farbe unseres Buttons von React-ish Blue in Angular-ish Red geändert, das ist mit Sicherheit Blasphemie!

Mit visuellen Schnappschusstests können wir sicherstellen, dass wir unsere visuellen Änderungen im Griff haben, anstatt die einzelnen Komponenten manuell zu überprüfen, haben wir die langweilige Aufgabe für unser Test-Framework übernommen.

Bisher war ich mit den Ergebnissen zufrieden, aber es gibt zwei Probleme, die hier behoben werden können:

  1. Wir möchten keine Snapshot-Tests für unsere Readme-Dateien durchführen, da dies nur zu Dokumentationszwecken gedacht ist. Es ist umständlich, die Snapshots jedes Mal zu aktualisieren, wenn wir unsere Readme-Dateien aktualisieren.
  2. Wir möchten, dass unsere Bild-Snapshot-Datei im Verhältnis zu den zugehörigen Komponenten bleibt.

In der ersten Ausgabe können wir unsere Readme-Geschichte mit einer einfachen NODE_ENV-Überprüfung abschließen:

Da der StoryShots-Image-Snapshot intern den Jest-Image-Snapshot verwendet, können wir für die zweite Ausgabe eine einfache Konfiguration übergeben, indem wir getMatchOptions hinzufügen:

Es gibt andere Konfigurationen, die wir an den Jest-Image-Snapshot übergeben können, z. B. Failure Threshold usw. Diese Liste der Konfigurationen finden Sie in der Dokumentation zum Jest-Image-Snapshot.

In der Continuous Integration (CI) -Umgebung möchten Sie möglicherweise sicherstellen, dass das Storybook bereit war, bevor Sie die Regressionstests durchführen. Normalerweise bevorzuge ich die Verwendung des statischen Build-Storybooks in der CI-Umgebung. Dazu führen wir eine neue Umgebungsvariable mit cross-env ein:

Garn hinzufügen Cross-Env

Dann müssen wir in unserer package.json neue Skripte erstellen, um sie in der CI-Umgebung ausführen zu können:

Wenn Sie die Umgebungsvariable "CI" auf "true" setzen, wird "create-react-app" so konfiguriert, dass "Jest" im nicht interaktiven Modus ausgeführt wird. Außerdem können Sie diese Umgebungsvariable verwenden, um die Storybook-URL in "Storyshots" so zu ändern, dass sie auf das statisch erstellte Storybook verweist:

Andere nützliche Addons

Ich mag im Allgemeinen alle Addons, die Storybook anbietet, aber es gibt nur wenige, die ich persönlich benutze:

  1. Knöpfe - Mit diesem Addon können wir interaktiv an den Requisiten unserer Komponenten basteln, um zu sehen, was mit den verschiedenen Requisiten passiert.
  2. Jest - Das Jest-Addon zeigt Ihre Jest-Testergebnisse direkt im Storybook-Eintrag Ihrer Komponente an.
  3. Ansichtsfenster - Mit diesem Addon können wir die Reaktionsfähigkeit unserer Komponenten bei verschiedenen Ansichtsfenstergrößen erkennen.
  4. GraphQL - Dieses Addon kann verwendet werden, um graphiQL IDE mit Beispielabfragen in Storybook anzuzeigen.
  5. Intl - Dieses Addon bietet einen Umschalter für das Gebietsschema "react-intl". Da "react-intl" meine i18n-Framework-Einstellungen sind, ist dieses Addon ein Muss für mich.

Fazit

Mit Storybook können Sie Ihre React-Komponentenbibliothek ganz einfach durchsuchen, verwalten und testen. Es ist schwierig, an einem großen Projekt mit vielen verschiedenen Teammitgliedern und unterschiedlichen Funktionen zu arbeiten. Hoffen wir, dass das Hinzufügen eines weiteren Satzes von Werkzeugen unter unseren Ärmeln unser Leben ein wenig erleichtert.

Vielen Dank fürs Lesen. Vergessen Sie auch nicht, das Demo-Repository zu lesen. Und wie immer Happy Hacking!