Der folgende Text ist ein Gastbeitrag von Daniel O’Connor. Daniel spricht mehr über OUI, die UI-Bibliothek von Optimizely, die Tom Genoni in Teil 1 eingeführt hat.
Vor über einem Jahr haben wir uns bei Optimizely auf die Mission begeben, unser Produktdesign zu vereinheitlichen und unsere stetig wachsende CSS-Größe in den Griff zu bekommen. Unser Kollege Tom Genoni, UI Engineer, leitete diese Bemühungen im Jahr 2014 und schuf unser Sass-Framework namens OUI.
Wir haben OUI zunächst in einen kleinen Teil der Optimizely-Anwendung integriert und es in den folgenden Monaten schrittweise in das gesamte A/B-Testing-Produkt übernommen. Seitdem haben wir ein komplett neues Produkt und eine Handvoll kleinerer Produkte unter Verwendung des Frameworks entwickelt. Diese Ausweitung des Umfangs stellte einzigartige Herausforderungen dar und erforderte, dass wir unsere Implementierungsstrategie verbessern.
In Teil 1 schrieb Tom über die allgemeinen Schritte, die zum Aufbau und zur Verbreitung von OUI erforderlich waren. In diesem Beitrag werde ich die Sass-Architekturentscheidungen diskutieren, die wir getroffen haben, und die Prozesse, die wir hinzugefügt haben, um OUI skalieren zu können.
Die Anatomie von OUI
OUI wurde außerhalb der Optimizely-Codebasis erstellt und befindet sich in einem eigenen Repository auf GitHub. Die Architektur ermöglicht es Entwicklern, die Standardstile einfach durch Überschreiben von Variablen zu ändern und Partial-Dateien (Komponenten und Objekte) zu erstellen, die gut mit dem Framework harmonieren.

Die obige Abbildung zeigt, wie wir OUI typischerweise in eine Anwendung integrieren. In der Praxis sieht die Datei `my_app.scss` typischerweise so aus:
// [1] Import OUI and app functions and mixins
@import 'oui/partials/elements/functions';
@import 'oui/partials/elements/mixins';
@import 'my_app/partials/elements/functions';
@import 'my_app/partials/elements/mixins';
// [2] Import OUI and app variables
@import 'oui/oui-variables';
@import 'my_app/my_app-variables';
// [3] Import OUI and app partials
@import 'oui/oui-partials';
@import 'my_app/my_app-partials';
// [4] Import OUI trumps
@import 'oui/partials/trumps/background';
@import 'oui/partials/trumps/borders';
@import 'oui/partials/trumps/layo ut';
@import 'oui/partials/trumps/margin';
@import 'oui/partials/trumps/padding';
@import 'oui/partials/trumps/sizing';
@import 'oui/partials/trumps/type';
Einige Anmerkungen zu den obigen SCSS-Dateien:
- Wir importieren zuerst die Mixins und Funktionen von OUI, gefolgt von allen benutzerdefinierten, die wir benötigen.
- Die Variablen von OUI werden direkt vor den Variablen unserer Anwendung geladen. Dies ermöglicht uns, bestehende Variablen anzupassen oder zu überschreiben und benutzerdefinierte hinzuzufügen.
- Dies ist der Kern der Datei. Die erste Partial-Datei importiert alle Basisregeln, Komponenten und Objekte von OUI, während die zweite dateispezifischen Code für unser Produkt importiert. Indem wir sie hier auflisten, stellen wir sicher, dass sie alle Standardvariablen sowie alle hinzugefügten oder geänderten Variablen unserer Anwendung übernehmen.
- Trumps, unsere Utility-Klassen, werden zuletzt geladen, da sie eine spezifische Aufgabe erfüllen und nicht überschrieben werden sollten.
Version 1: Grundlegende Integration von OUI mit npm
Das Hosten von OUI auf GitHub gibt uns die Freiheit, es einfach in Projekte zu integrieren, indem wir npm verwenden. Zunächst nutzten wir es nur, um den aktuellsten OUI-Commit von GitHub zu beziehen, der in der Optimizely-Anwendung funktionieren würde.
npm install --save git://github.com/optimizely/oui.git#commit-hash
Tatsächlich kann jedes GitHub-Repository mit dieser Methode als Abhängigkeit installiert werden. Und die Angabe des Commit-Hashes ist eine unkomplizierte Methode, um zu verhindern, dass brechende Änderungen in OUI automatisch bezogen werden. Mit diesem Prozess werden Verweise auf OUI in `my_app.scss` auf das Verzeichnis `node_modules/` (den Standardinstallationsort für npm) verwiesen.
// Before:
@import 'oui/partials/elements/functions';
// After:
@import 'path/to/node_modules/oui/partials/elements/functions';
Alternativ könnten wir `oui/` nach `pfad/zu/node_modules/oui/` verlinken.
Dieser grundlegende Ansatz funktionierte einige Monate lang, aber es tauchten Fragen auf, als wir begannen, OUI in andere Projekte zu integrieren. Wie können Anwendungen OUI-Fehlerkorrekturen und andere nicht-brechende Änderungen *automatisch* beziehen? Wie können wir Kontext bei der Aktualisierung auf eine neue Version von OUI bereitstellen? Und wie können wir die Dokumentation auf dem neuesten Stand halten, während wir uns schnell bewegen? Wir wussten, dass wir es besser machen konnten!
Version 2: Fortgeschrittene Implementierung von OUI
Um OUI wirklich robust und entwicklerfreundlich zu gestalten, haben wir auf unserer bisherigen Arbeit aufgebaut und eine Reihe von technischen Werkzeugen und Best Practices genutzt. Obwohl diese Schritte fortgeschrittener sind, erwiesen sie sich für uns als unverzichtbar.
- Verwendung von npm und semantischer Versionierung
- Hinzufügen eines Änderungsprotokolls
- Implementierung eines Build-Systems
- Erstellung einer dynamischen Dokumentationslösung
Versionierung
OUI ist seit über einem Jahr in Entwicklung, aber brechende Änderungen sind immer noch häufig. Eine brechende Änderung, wie zum Beispiel das Umbenennen von Flexbox-Klassen, kann Stunden sorgfältiger Suchen und Ersetzen erfordern, um sie in einer großen Codebasis zu unterstützen.
Wie bereits erwähnt, haben wir OUI zunächst über npm von GitHub bezogen und einen Commit-Hash eingebunden, um zu verhindern, dass brechende Änderungen automatisch abgerufen werden. Diese Lösung ist langsam, da der Commit-Hash in der `package.json` einer Anwendung für jede neue Änderung aktualisiert werden muss. Idealerweise sollten abwärtskompatible Änderungen wie Fehlerkorrekturen und neue Komponenten automatisch bezogen werden.
Dies haben wir erreicht, indem wir OUI auf npm veröffentlicht haben, die semantische Versionierung in unseren Versionsnummern befolgen und NPM konfigurieren, um kleine und Patch-Änderungen zu akzeptieren. Mitwirkende an OUI identifizieren brechende Änderungen und ändern die Versionsnummern entsprechend.
Führen eines Änderungsprotokolls
Das Upgrade auf die neueste Version von OUI innerhalb eines Projekts kann ohne Kontext oder klare Versionshinweise schwierig sein. Wir haben ein Änderungsprotokoll (basierend auf Keep a Changelog) erstellt, um alle Commits und Pull-Requests zu verfolgen. Dies erleichtert die Erstellung hilfreicher Versionshinweise, die Entwicklern, die OUI implementieren, genau zeigen, was sie bei der Aktualisierung auf eine neue Hauptversion korrigieren oder ändern müssen.
Linting und Kompilieren von SCSS mit Travis CI
Wir verwenden scss-lint, um einen konsistenten Stil zu wahren, und führen node-sass aus, um sicherzustellen, dass das SCSS kompiliert wird. Wir haben die grundlegenden Lint- und Kompilierungsprüfungen in GitHub Pull Requests über die Travis CI-Integration von GitHub integriert.
Dies stellt sicher, dass der Code sauber ist und verhindert, dass offensichtliche Fehler zusammengeführt werden. Es hat auch den zusätzlichen Vorteil, dass ein Teil des Code-Review-Prozesses automatisiert wird, sodass sich die Gutachter auf die wichtigen Teile konzentrieren können.
Erstellung von lebendiger Dokumentation
Dutzende von Ingenieuren nutzen OUI. Um sicherzustellen, dass jeder das Framework nutzen kann, müssen wir über gut dokumentierten Code verfügen. Wir verwenden ScribeSass, ein Inhouse entwickeltes Node.js-Modul, um eine Dokumentationswebsite (noch nicht online) basierend auf Kommentaren im SCSS-Code automatisch zu generieren. Wir werden es bald als Open-Source-Projekt veröffentlichen.
Wir haben OUI vor über einem Jahr in die Optimizely-Codebasis eingeführt. Die Architekturentscheidungen, die OUI flexibel machen, und die Investition in Werkzeuge und Prozesse haben es uns ermöglicht, es in fünf Repositories zu integrieren, neue Mitwirkende einfach einzuarbeiten und einem Team von Softwareentwicklern zu ermöglichen, HTML zu schreiben, ohne neues CSS einzuführen.
Wir ermutigen Sie, sich im Repository auf GitHub umzusehen, unsere Dateien CONTRIBUTING.md und README.md zu lesen und sich bei Fragen zu melden!