Wenn Ihr Unternehmen mehrere Produkte im gleichen Stil herstellt, werden Sie eines Tages auf die Idee kommen, eine Bibliothek mit einem gemeinsamen Code zu erstellen. Zum Beispiel mit UI-Komponenten, einem Autorisierungsdienst oder zum Arbeiten mit APIs von Drittanbietern. Sie fragen sich vielleicht: Wer sollte diesen Code unterstützen? Wie kommuniziere ich Änderungen an Benutzer? Wie bringen Sie sie dazu, Ihre Bibliothek überhaupt zu nutzen?
Seit 2015 arbeite ich bei Tinkoff in der Abteilung Business Services. In dieser Zeit ist unser Team von 3 auf über 60 Entwickler gewachsen, und das Tinkoff Business-Ökosystem ist von 3 auf 50 Webanwendungen gewachsen. In verschiedenen Phasen unserer Entwicklung haben wir uns auf unterschiedliche Weise der Arbeit mit gemeinsamem Code zugewandt, und ich möchte in diesem Artikel darauf eingehen.

Grundlage: billig und fröhlich
Also schnell vorwärts bis 2015. Wir haben nur drei Webanwendungen: Cash Management Services, Payroll Project und Control Panel. Und so viele Entwickler.
Anwendungsschnittstellen werden im gleichen Stil erstellt, und der allgemeine Code wird in einem separaten Repository in die Foundation-Bibliothek verschoben. Die Bibliothek wird nicht kompiliert - und genau genommen gibt es dort nichts zu kompilieren. Der gesamte Code auf ES5 wird nicht in npm veröffentlicht, sondern durch den Namen des Zweigs in package.json verbunden. Für Produktversionen wurden separate Foundation-Release-Zweige erstellt, um den Status zu korrigieren. Wenn wir vergessen haben, den Foundation-Zweig festzuschreiben, stellte sich mit dem Hotfix heraus, dass sich die Foundation geändert hatte und die Hotfix-Version einfach nicht funktionieren würde.
So sah die Foundation-Verbindung in package.json aus:
"dependencies": { ... "sme-foundation": "git+https://stash_url/sme-foundation.git#develop" ... },
Das Hauptprinzip der Bibliothek zu diesem Zeitpunkt ist der allgemeine Besitz von Code.
Wenn für eine Produktfunktion eine Überarbeitung der Foundation erforderlich war, hat der Funktionsentwickler dies selbst durchgeführt. Und wenn sie mit der vorherigen Version nicht kompatibel waren, regelt er auch die Verwendung dieses Codes in allen Projekten. Gleiches gilt für das umfangreiche Refactoring: Wenn Sie eine Komponente umgestalten und ihre API ändern möchten, gehen Sie bitte alle Verwendungszwecke durch.
Wenn Sie in einem Projekt das wiederverwenden möchten, was sich bereits in einem anderen befindet - auch kein Problem -, bringen Sie es einfach in die Bibliothek.
Zum Glück gab es nicht viel Code. Dieser Ansatz funktionierte hervorragend für drei, vier, fünf Projekte ... und hatte eine Reihe von Vorteilen:
- Der gemeinsame Code befand sich an einer Stelle und wurde in Projekten wiederverwendet.
- Projekte entwickelten sich schneller.
- Die Bibliothek wuchs.
- Jeder kannte sowohl den allgemeinen Kodex als auch die Projekte, wodurch die Überprüfung und Annahme von Architekturentscheidungen effizienter wurde.
- Die Notwendigkeit, den allgemeinen Code zu verfeinern, hat die Entwicklung von Funktionen nicht blockiert.
Zu diesem Zeitpunkt hatten wir ein Minimum an Dokumentation: einige JSDoc- und Unit-Tests. Für die UI-Komponenten gab es nicht genügend visuelle Fensteranzeige, und wir sahen eine billige und schnelle Lösung - Demo-UI. Tatsächlich war es eine eckige Anwendung, auf deren Seiten die Komponenten selbst und das entsprechende Markup eingefügt wurden.

Im Jahr 2019 ist es unwahrscheinlich, dass Sie dasselbe tun. Aber hier ist, was aus dieser Geschichte gelernt werden kann:
- Das Teilen von gemeinsamem Code eignet sich hervorragend für kleine Teams.
- Auch wenn Sie nur zu dritt sind, seien Sie nicht faul, einen wiederholten Code zu erstellen. Dies steht Teams jeder Größe zur Verfügung.
- Selbst eine normale Seite mit einer Liste von Komponenten kann Ihr Leben erheblich vereinfachen.
Im Laufe der Zeit wuchs das Ökosystem- und Entwicklungsteam von Tinkoff Business. Als es mehr als ein Dutzend Projekte gab, funktionierte dieser Ansatz nicht mehr.
Das Wechseln gemeinsamer Komponenten ist zu teuer geworden. Der Entwickler eines Projekts war nicht mehr mit allen anderen Projekten vertraut, die Suche nach der Verwendung von Komponenten und das Vornehmen von Änderungen wurde komplizierter. Die Zeit für die Implementierung neuer Funktionen, die sich auf die Stiftung auswirken, nahm zu.
Neue Entwickler hatten kein vollständiges Bild davon, was getan wurde und wie es verwendet wurde.
Das Ändern der API der Komponente war beängstigend. Aus diesem Grund wurden Frankenstein-Komponenten mit einer großen Anzahl von Eingabeparametern angezeigt.
Manchmal führte dies zu
Inkonsistenzen in der UX . Details wie das Arbeiten mit der Tastatur und das Arbeiten mit dem Fokus wurden in verschiedenen Komponenten unterschiedlich implementiert. Und irgendwo wurden sie überhaupt nicht implementiert, weil sich die Entwickler auf Geschäftsfunktionen konzentrierten.
Andere Angular-Projekte erschienen im Unternehmen, und wir schlugen vor, dass sie auch unsere Bibliothek nutzen. Zuerst waren sie sich sogar einig ... Aber sobald Verbesserungen nötig waren, befanden wir uns in einer schwierigen Situation: Alle unsere Entwickler sind mit ihren Projekten beschäftigt, und unsere Kollegen haben keine Motivation, sich mit der Bibliothek eines anderen zu befassen.
Jeder war für die Stiftung verantwortlich und niemand besonders, und das passte nicht zu Kollegen.
UI Kit und ein neuer Ansatz zur Arbeitsorganisation
Als es 2017 um das Redesign und das neue UI-Kit ging, haben wir begonnen, neue Komponenten auf andere Weise zu entwickeln. Zunächst haben wir ein engagiertes Team.
Das Team
Wir haben drei Personen aus Produktteams ausgewählt und gesagt: „Jetzt stellen diese Leute UI-Komponenten für andere Projekte her.“
Was hat das engagierte Team gegeben?
- Zunächst haben wir in kurzer Zeit die Grundkomponenten für Produktteams vorbereitet. Zwei Wochen nach Beginn der Entwicklung erhielten die Kollegen das Notwendigste. Und dann haben wir die Bibliothek entwickelt, wobei wir uns auf die Prioritäten der Kunden konzentriert haben.
- Das engagierte Team konzentrierte sich speziell auf Komponenten und UX. Unsere Aufgabe war es, Komponenten herzustellen, die sowohl aus Sicht des Endbenutzers der Schnittstellen (korrekte Einrückung, Kontraste, Arbeit mit der Tastatur - dies war keine Kleinigkeit für das Wal-Team) als auch aus Sicht der Entwickler von Produktteams (konsistente API, bequeme Verbindung, Erweiterbarkeit) qualitativ sind. .
- Ein engagiertes Team ist eine Verantwortung. Wenn eine Komponente in einer Komponente gefunden wird, wird der Produktentwickler nicht mit ihm allein gelassen. Kritische Fehler werden mit hoher Priorität behoben und ein Hotfix wird vorbereitet, während weniger kritische Fehler in der Reihenfolge ihrer Priorität behoben werden. Hier ist anzumerken, dass vor dem Erscheinen des hervorgehobenen Teams Fehler, die für Produktteams nicht kritisch waren (z. B. die Farbe des Platzhalters in der Eingabe und in der Auswahl ist geringfügig unterschiedlich), lange Zeit im Rückstand liegen und Geschäftsmerkmalen weichen könnten. Für das Wal-Team hat das Erscheinungsbild der Komponenten jedoch oberste Priorität.
Wenn sich das Know-how in Bezug auf Komponenten auf ein Team konzentriert, wie kann man dann anderen den Umgang mit diesen Komponenten beibringen? Dafür haben wir eine hervorragende Dokumentation erstellt.
Die Dokumentation
Die Idee, unseren Demo-Stand neu zu gestalten, ist schon lange in der Luft und die Entwicklung einer neuen Bibliothek hat es möglich gemacht.
Dann wurde das Storybook für Angular noch nicht veröffentlicht, also gingen wir unseren eigenen Weg. Es ist das Beste: Unsere eigene Implementierung hat unsere Vorstellungskraft nicht eingeschränkt, wir konnten absolut alles tun, was wir wollten.
Und hier ist was wir getan haben:
- Es wurden Informationen zur gesamten Bibliothek hinzugefügt: eine schrittweise Beschreibung der Verbindung und eine Liste der unterstützten Browser.

- Wir haben eine detaillierte Beschreibung jeder Komponente erstellt: Warum sie benötigt wird, wie sie verbunden ist, welche Eingabe-Ausgabe-Parameter sie unterstützt (mit der Fähigkeit, sie zu stecken, a la Storybook), Beispiele für die typische Verwendung, eine Liste ähnlicher Komponenten.


- Es wurde eine Liste der Projekte hinzugefügt, in denen diese Komponente verwendet wird.

- Sie begannen, Statistiken über die Verwendung des Wals in verschiedenen Projekten zu sammeln: Welche Projekte sind verbunden, welche Version, wie viele Komponenten werden verwendet, welche Version des Winkels und des Wals in jedem Projekt - diese Informationen werden verwendet, um inkompatible Änderungen zu planen und die Unterstützung alter Versionen des Frameworks zu verweigern. Eine Beschreibung des Tools, das diese Statistiken sammelt, verdient einen separaten Artikel.

- Versionsverwaltung hinzugefügt: Dokumentation für jede zuvor veröffentlichte Version des UI-Kits anzeigen.

Natürlich erschien dies alles nicht sofort, sondern entwickelte sich weiter.
Innerhalb unserer Abteilung würde ein engagiertes Team und eine Dokumentation völlig ausreichen. Kollegen sind es gewohnt, allgemeinen Code zu verwenden, sie kennen die Entwickler des UI-Kits und sind im Allgemeinen sehr loyal.
Das UI-Kit-Design selbst wurde jedoch für alle Produkte des Unternehmens als gemeinsam positioniert, was bedeutet, dass Dutzende von Teams dieselben Komponenten benötigten - von internen HR-Projekten bis hin zu WebOffice, einem funktionierenden System für Zehntausende von Remote-Mitarbeitern. Daher stand das Wal-Team vor einer umfassenderen Aufgabe: ein qualitativ hochwertiges internes Produkt zu entwickeln, das alle Angular-Teams verwenden werden.
Im Allgemeinen waren Kollegen aus anderen Abteilungen positiv, aber sie hatten immer noch einige Zweifel: ob die benötigten Funktionen schnell genug entwickelt werden würden, ob sie von hoher Qualität wären ... Jemand hatte bereits begonnen, Komponenten selbst herzustellen.
Um diese Zweifel auszuräumen, haben wir die Arbeit so transparent wie möglich organisiert.
Transparenz
Wenn Sie nur einen Gedanken aus diesem Artikel herausnehmen, lassen Sie es die folgende Idee sein: Um eine Bibliothek erfolgreich zu machen, reicht es nicht aus, gute Komponenten zu erstellen. Sie sollten so transparent und kundenorientiert wie möglich sein. In diesem Fall sind Kunden Endproduktentwickler.
Sie müssen Ihren Kollegen auf jeden Fall vermitteln, was Sie tun, warum und wie Sie es verwenden.
Welche Tools haben wir verwendet?
Regelmäßige Veröffentlichungen und Demos. Die erste Demo fand zwei Wochen nach Beginn der Entwicklung statt und fand dann wöchentlich statt - am Tag der nächsten Veröffentlichung. Manchmal gab es viele neue Funktionen und manchmal nur Fehlerbehebungen. Wir haben eine Demo gemacht, egal was passiert.
Mit Blick auf die Zukunft werde ich sagen, dass die Hauptarbeit nun abgeschlossen ist, sich die API stabilisiert hat und das Team auf alternative Versionen umgestellt hat - eine Version mit Funktionen, eine mit Änderungen und Verbesserungen - und die Demo wird nur für Versionen mit neuen Funktionen durchgeführt.
Changelog . Wir haben konventionelle Commits eingeführt und daraus ein Changelog erstellt, was den Übergang zu neuen Versionen für Teams erheblich vereinfacht hat.
"Responsive" Team . Wie alle Teams haben wir einen eigenen Kanal in Slack, das ist nichts Neues. Wir haben sogar zwei Kanäle: einen für die Kommunikation innerhalb des Teams und einen für Benutzer - Antworten auf Fragen, Ankündigungen, Umfragen, Durchführung von Demos und andere Aktivitäten.
Es ist wichtig, dass eingehende Fragen wirklich gelöst werden. Einige der Fragen sind in diesem Fall kompliziert, andere wiesen auf die Lücken in der Dokumentation hin (oder lassen Sie uns wissen, dass nicht jeder sie liest). Und manchmal schrieben Neulinge in Angular über ihre Schwierigkeiten. Das Wal-Team mit gleicher Bereitschaft half allen, nicht faul anzurufen, wenn das Problem im Chat nicht behoben wurde, oder sogar den Code eines anderen in sich selbst herunterzuladen. Natürlich verschwenden solche Kommunikationen Zeit für Entwickler, aber dies ist Teil der Arbeit an der Bibliothek.
Mittlerweile gibt es mehr als 200 Benutzer im Walkanal, und viele Fragen werden ohne Beteiligung der Walentwickler gelöst: Kollegen teilen ihre Erfahrungen und beantworten sich gegenseitig ihre Fragen.
Newsletter mit einer Liste der Änderungen nach der Veröffentlichung. Ihre Zielgruppe sind Entwickler, Manager und Produktdesigner. In den Newslettern wurden die Änderungen einfach und leicht beschrieben - was in Changelog nicht immer möglich ist - und enthielten Bilder von „war / wurde“. Ich bin mir immer noch sicher, dass dies ein großartiges Werkzeug ist, aber es war schwierig, jede Woche hochwertige und klare Digests zu erstellen. Nach einiger Zeit haben wir aufgehört, sie zu senden, aber vielleicht werden wir zu dieser Praxis zurückkehren.
Benutzerumfragen bieten eine Außenansicht und zeigen Schwachstellen auf. Den Ergebnissen der nächsten Umfrage zufolge haben wir beispielsweise festgestellt, dass die meisten Kollegen voll und ganz der Meinung sind, dass die Entwickler des UI-Kits bereit sind, zu helfen, was bedeutet, dass wir in dieser Richtung alles richtig machen. Mit der Aussage „Neue Komponenten werden schnell entwickelt“ stimmten jedoch weniger Befragte zu. Was tun mit solchen Ergebnissen? Machen Sie einerseits alle Teammitglieder darauf aufmerksam und arbeiten Sie an Schwachstellen. Arbeiten Sie andererseits mit Benutzern. Wenn es auf Geschwindigkeit ankommt, achten Sie mehr auf die Erklärung, woher solche Begriffe stammen.

Die Umfragen umfassten offene Fragen wie „Was können wir verbessern?“. Ich muss sagen, dass unsere Kollegen uns einige wertvolle Tipps gegeben haben: Zum Beispiel, um die Schaltfläche Kopieren für Codebeispiele zu erstellen oder unseren Klassen beizubringen, dass Daten mit Unixtime funktionieren.
Teamrolle
Oben habe ich bereits über das „Responsive Team“ geschrieben, das viel für den Erfolg der Bibliothek im gesamten Unternehmen entscheidet. Ich möchte diese Idee noch einmal betonen und über zwei verwandte Praktiken sprechen.
Pflicht . Irgendwann wurde die Kommunikation mit Kollegen so intensiv, dass die Einführung von Pflichten unvermeidlich schien. So viele Serviceteams in Tinkoff arbeiten. Einmal am Tag, zwei Tage, eine Woche ist eines der Teammitglieder im Dienst. Er überwacht den Kanal, beantwortet Fragen und übernimmt den größten Teil der Kommunikation, während seine Teamkollegen nicht durch Unterstützung abgelenkt werden.
Wir haben diesen Punkt noch nicht erreicht und im Laufe der Zeit ist die Notwendigkeit verschwunden. Anderen Einsatzteams wird jedoch geholfen.
Audit Niemand kennt die Komponenten eines Wals besser als das Team, das sie entwickelt. In mehr als zwei Jahren Entwicklungszeit haben die Jungs auch hervorragende Kenntnisse in Angular gesammelt. Jetzt führen wir die Praxis der „Audits des Wal-Teams“ ein. Die Jungs verbinden sich mit der Überprüfung von Produktprojekten und sehen sich die Endprodukte und ihren Code an. Ihr Ziel ist es, Missbrauch zu identifizieren, die Dokumentation zu verfeinern und eine Liste mit guten und schlechten Praktiken zu erstellen. Wir werden darüber sprechen, was beim nächsten Mal passiert.
Herausforderungen und Kompromisse
Wie bei jedem Prozess mit einer großen Anzahl von Stakeholdern zwingt uns die Entwicklung einer gemeinsamen Bibliothek dazu, Kompromisse einzugehen.
Es war nicht einfach für uns, ein Gleichgewicht zwischen Codequalität und API-Stabilität zu finden. Einerseits änderte sich das Design zu Beginn der Arbeit: Neue Komponenten oder neue Zustände alter Komponenten erschienen; etwas im Gegenteil war veraltet und abgesägt. Andererseits änderte sich die Vision der Entwickler hinsichtlich der richtigen Komponenten-API. All dies führte unweigerlich zu bahnbrechenden Veränderungen. Aber die Anzahl der Bibliotheksbenutzer wuchs, und unsere bahnbrechenden Änderungen verursachten ihnen große Unannehmlichkeiten.
Wir haben einen Kompromiss gefunden: Nicht öfter als bei jeder fünften Veröffentlichung, dh alle fünf Wochen, Änderungen vorzunehmen. Beispielsweise könnten solche Änderungen die Releases 0.50, 0.55, 0.60 erfordern. Der Übergang von 0,50 auf 0,51 erforderte jedoch keinen Aufwand. Dies dauerte bis zur Veröffentlichung der stabilen Version 1.0.0. Jetzt ist die API stabil und alle umfangreichen Änderungen werden auf unbestimmte Zeit auf 2.0.0 verschoben.
Der Wechsel zu einer neuen Version erforderte mehrmals viel Routinearbeit: Umbenennen von Präfixen, Ändern von Symbolimporten und dergleichen. Für solche Fälle haben wir Migrationsskripte implementiert.
Schlussfolgerungen
Dieser Artikel beschreibt unsere vierjährige Erfahrung in der Arbeit mit gemeinsam genutzten Codebibliotheken. Welche Schlussfolgerungen haben wir gezogen?
- Selbst ein kleines Team sollte es nicht ertragen, Code zu duplizieren. Das Entfernen von Code in die Bibliothek ist eine Lösung, auf die jeder zugreifen kann.
- Das gemeinsame Eigentum an gemeinsamem Code funktioniert gut für kleine Teams. Bis zu 10 Projekte sind Benutzer der Bibliothek.
- Mit der wachsenden Anzahl von beteiligten Projekten oder Entwicklern ist es bequemer, ein Team hervorzuheben, das sich auf gemeinsamen Code konzentriert.
- Ein wichtiger Teil der Arbeit eines engagierten Teams ist die Kommunikation mit Benutzern: Demo, Schulung, Hilfe, Dokumentation.
- Haben Sie keine Angst, weiter zu denken und Zeit in Werkzeuge zu investieren. In unserem Fall ist dies eine praktische Präsentation mit Dokumentation und einem Analysegerät für die Verwendung von Komponenten.