Methoden zum Umgang mit Legacy-Code am Beispiel von GitLab

Sie können endlos betrügen, ob GitLab ein gutes Produkt ist. Es ist besser, sich die Zahlen anzusehen: Laut den Ergebnissen der Investitionsrunde betrug die GitLab-Bewertung 2,7 Milliarden US-Dollar, während die vorherige Bewertung 1,1 Milliarden US-Dollar betrug. Dies bedeutet ein schnelles Wachstum und das Unternehmen wird immer mehr Front-End-Entwickler einstellen.

Dies ist die Geschichte des Auftretens des Frontends in GitLab.



Dies ist eine grafische Darstellung der Anzahl der Front-End-Anbieter in GitLab, beginnend im Jahr 2016, als sie überhaupt nicht da waren, und endend im Jahr 2019, als es bereits einige Dutzend von ihnen gab. Aber GitLab selbst gibt es schon seit 7 Jahren. Bis 2017 wurde der Hauptcode im Frontend von Backend-Entwicklern geschrieben, schlimmer noch von den Backend-Entwicklern auf Ruby on Rails (auf keinen Fall möchten wir jemanden beleidigen und unten erklären, wovon wir sprechen).

Seit 7 Jahren ist jedes Projekt, ob Sie es mögen oder nicht, veraltet. Irgendwann kann das Refactoring nicht mehr verschoben werden. Und die Reise beginnt voller Abenteuer, deren Endpunkt niemals erreicht wird. Wie das in GitLab passiert, sagte Ilya Klimov.


Über den Sprecher: Ilya Klimov (xanf) Senior Frontend Engineer bei GitLab. Zuvor war er in Startups und Outsourcing tätig und leitete ein kleines Outsourcing-Unternehmen. Dann wurde mir klar, dass ich noch keine Zeit hatte, das Produkt auszuarbeiten, und ich kam zu GitLab.

Der Artikel basiert auf einem Bericht von Ilya bei FrontendConf , daher strukturiert er die Informationen nicht so sehr, als dass er die Erfahrung des Sprechers widerspiegelt. Es mag übermäßig gesprächig erscheinen, ist aber unter dem Gesichtspunkt der Arbeit mit dem Erbe nicht weniger interessant.

In GitLab migrieren sie wie in vielen anderen Projekten allmählich von alten Technologien zu etwas Relevanterem:

  • CoffeeScript in JavaScript. Entwickler von Ruby on Rails, als sie das Projekt starteten, konnten nicht anders, als auf CoffeeScript zu achten, das Ruby sehr ähnlich sieht.
  • JQuery Vue. , JQuery. GitLab SPA. server-side rendering progressive enhancement, Vue-. , : Vue-, .
  • Karma Jest. Jest - . Karma , , .
  • REST GraphQL , , Vuex Apollo. Vuex, Redux Vue, Apollo local state , . GraphQL , .

Gleichzeitig erfolgt der Austausch in mehrere Richtungen gleichzeitig, im Projekt gibt es gleichzeitig einen Legacy-Code in verschiedenen Phasen.

Stellen Sie sich nun vor, Sie kommen zu einem Projekt, das sich mitten in all diesen Migrationen befindet. Der Standard und Bezugspunkt für mich war die Situation, in der Sie die Bearbeitung eines Projekts öffnen, auf die Schaltfläche Speichern klicken - und was kommt Ihrer Meinung nach? Wenn Sie dachten, dass wir so alte Phagen sind, dass HTML kommt, dann nein. JavaScript kommt ins Spiel, dass Sie sich "weiterentwickeln" müssen, um ein Popup-Fenster anzuzeigen. Dies ist der tiefste Punkt in meinem Legacy-Bild.

Weiter oben: selbstgeschriebene Klassen in jQuery, Vue-Komponenten und als höchster Punkt neue moderne Funktionen, die mit Vuex, Apollo, Jest usw. geschrieben wurden.

So sieht mein Beitragsdiagramm auf GitLab aus.



Darin - und das ist sehr wichtig für das Verständnis der Essenz der Geschichte und all meiner Schmerzen - können mehrere Segmente unterschieden werden:

  • Onboarding im April-Bereich. "Flitterwochen", als ich gerade bei GitLab angefangen habe. Zu diesem Zeitpunkt erhalten Anfänger einfachere Aufgaben.
  • Von Ende April bis Mitte Mai gibt es nur wenige Verpflichtungen - eine Zeit der Ablehnung : „Nein, es kann nicht sein, dass alles so gemacht wird!“ Ich habe versucht zu verstehen, wo ich etwas nicht verstehe, daher gibt es so wenige Commits.
  • Die zweite Maihälfte ist Wut : "Ich kümmere mich nicht um alles - ich muss die Produktion verschieben, Features teilen, versuchen, etwas dagegen zu tun."
  • Anfang Juni (Zero Commits) ist eine Depression . Dies war kein Urlaub, ich sah und verstand, dass meine Hände fielen, ich weiß nicht, was ich damit machen soll.
  • Danach stimmte ich mir selbst zu und entschied, dass ich als Profi eingestellt wurde, und ich kann GitLab besser machen. Im Juni und Juli habe ich eine Vielzahl von Verbesserungen angeboten. Nicht alle von ihnen haben aus Gründen Resonanz gefunden, über die wir sprechen werden.
  • Jetzt bin ich in der Phase der Adoption und verstehe klar: wie, wo, warum und was ich mit all dem anfangen soll.

Ich werde Ihnen genauer erzählen, was ich von August bis Oktober getan habe. Ehrlich gesagt, in einem kleinen Outsourcing-Unternehmen oder in einem Startup wäre ich in diesen drei Monaten fünf Mal mit einer solchen Produktivität entlassen worden.

Also habe ich in drei Monaten:

  • Segmentierte Steuerung - drei Tasten.
  • Die Suchzeichenfolge, in der der lokale Verlauf gespeichert ist, ist eine etwas komplexere Komponente.
  • Spinner. Und diese Komponente ist noch nicht eingefroren.



Als nächstes werden wir Schritt für Schritt analysieren, warum dies passiert ist und wie man damit lebt. Wenn es Ihnen so vorkommt, als würde ich übertreiben, finden Sie hier einen Screenshot einiger Aufgaben, die bei GitLab an mir hängen (Sie können direkt auf GitLab schauen, es ist geöffnet).



Siehe: verpasste 12.1, verpasste 12.2, verpasste 12.3. Der Sprint dauert einen Monat und die segmentierte Kontrolle - 3 Sprints. Spinner ist immer noch weg, er wird unsere Hauptfigur sein.

Das Problem des Refactorings und die Philosophie des Refactorings beschäftigen sich seit Jahrtausenden mit der Menschheit. Jetzt werde ich beweisen:
« ; , , ; ; , .

, , , : ».

Die Bibel sagt uns, wie man alte und neue Funktionen kombiniert. Der zweite Teil des Zitats ist aus Sicht des Managements wertvoll: Unabhängig davon, wie Sie Initiativen ergreifen, werden Sie auf großen Widerstand stoßen.

In der Depressionsphase habe ich viele Berichte über die Umgestaltung großer Projekte gesehen, aber ungefähr 70% von ihnen erinnerten mich an einen Witz.

Javist talk:
- Wie beschleunigen wir unsere Java-Anwendung?
- Oh, also hatte ich einen Bericht darüber! Willst du erzählen
- Um zu sagen und ich kann, würde ich beschleunigen!

Wenn Sie sich dennoch für den gefährlichen und wackeligen Weg des Refactorings entscheiden, habe ich einige einfache Rezepte, die ich für mich selbst entwickelt habe und die unter realitätsnahen Bedingungen funktionieren.

1. Isolierung


Um die Dinge zu beschleunigen, zu verbessern, umzugestalten, müssen Sie den Elefanten in Steaks schneiden, dh die Aufgabe in Teile teilen. GitLab ist sehr groß, wir haben einen Slack-Kanal "Ist das bekannt", in dem Leute Fragen stellen wie "Ist das ein Fehler oder eine Funktion, wer kann das erklären?" - und die Antwort wird nicht immer gefunden.

Ein einfaches Beispiel: Screenshots derselben Stelle in GitLab, aufgenommen mit einem Unterschied von einem Tag.



Ich war sehr verärgert, weil ich an dieser Schaltfläche gearbeitet habe, und das ist alles auf die eine oder andere Weise Probleme mit der Schaltfläche.

Was ist passiert? Es ist ganz einfach: Wir entwickeln ein Design-System und haben als Teil eines separaten Storybook-Tools zum Testen eines Design-Systems das globale CSS-GitLab deaktiviert, um zu überprüfen, wie CSS-Komponenten vom globalen CSS isoliert sind.

Zusammenfassend: CSS wird nicht mehr gespeichertZumindest in GitLab.

Ich arbeite seit 14 Jahren mit JavaScript und habe noch nie ein Projekt gesehen, bei dem mindestens ein oder zwei Jahre lang vollständig verwaltetes CSS erhalten bleibt. HTML kann übrigens auch nicht gespeichert werden (sicher in GitLab).

GitLab wurde für eine lange Zeit und Backendov entwickelt. Sie trafen eine kontroverse Entscheidung für Bootstrap, da Bootstrap ein Backend-freundliches Layoutsystem bot.

Aber was ist Bootstrap in Bezug auf die Philosophie der Komponentenisolation? Dies sind ungefähr 600-700 globale Klassen (tatsächlich ist jede CSS-Klasse global), die die gesamte Anwendung durchdringen. In Bezug auf die Verwaltbarkeit wird nichts Gutes daraus.

Die nächste Aktion (nennen wir es nicht einen Fehler) - GitLab hat Vue.js übernommen. Die Wahl war vernünftig, aufgrund der drei Frameworks ist es Vue, mit dem Sie etwas am reibungslosesten umschreiben können. Sie müssen eine große Einzelseitenanwendung nicht sofort wegwerfen und ausschneiden, sondern können einzelne kleine Knoten neu schreiben. Jetzt kann es auf Angular ausgeführt werden, aber vor 3-4 Jahren, als Angular 2 erschien, konnte es in mehr als einer Instanz nicht auf einer Seite koexistieren. Jetzt ist auch eine Reaktion möglich, aber all diese Magie mit dem Fehlen eines Build-Schritts und so weiter brachte die Waage in Richtung Vue.

Infolgedessen wurde ein Übel mit dem zweiten kombiniert. Dies ist schlecht, da Bootstrap-Stile nichts über das Komponentensystem wissen und Vue-Komponenten ohnehin zuerst geschrieben wurden. Daher wurde eine willensstarke Entscheidung getroffen, ein eigenes Designsystem zu schaffen. Wir haben es genanntPyjamas , aber niemand konnte mir erklären warum.

Ich sehe, dass es jetzt immer mehr eigene Designsysteme gibt, und das ist schön.

Das Design-System ist isoliert, aber da GitLab bereits in Bootstrap geschrieben wurde, sind ungefähr 50-60% unseres Design-Systems ein Wrapper über Bootstrap / Vue-Komponenten mit einer Verringerung ihrer Funktionalität. Dies ist erforderlich, damit Sie im Konstruktionssystem die Komponente nicht falsch verwenden können. Wenn wir über eine abstrakte Bibliothek sprechen, ist Flexibilität dort wichtig, zum Beispiel die Möglichkeit, jede gewünschte Schaltfläche zu erstellen. Wenn in GitLab Spinner vier Größen haben können, die von Designern genehmigt wurden, müssen Sie dies physisch nicht zulassen.

Eines Tages wird das Gute gewinnen, und wir werden ein wichtiges Tool haben, mit dem Sie natürlich Front-End-Projekte effektiv umgestalten können, wenn Sie bei der Unterstützung von IE und Edge punkten - dies ist das Shadow DOM . Shadow DOM löst das Problem, dass globale Stile in Komponenten fließen. Bitte nehmen Sie kein Polymer, das selbst Google bereits begraben hat. Verwenden Sie lit-element und lit-HTML, und Sie können isolierte Stile mit Ihrem bevorzugten Framework erstellen.

Sie können sagen, dass React CSS-Module hat, Vue Stile mit Gültigkeitsbereich, die dasselbe tun. Seien Sie sehr vorsichtig mit ihnen: CSS-Module bieten keine 100% ige Isolation, da sie nur mit Klassen arbeiten. Und mit Stilen mit Gültigkeitsbereich in Vue kann ein sehr interessantes Szenario realisiert werden, wenn die Stile der obersten Komponente in das Stammelement des übergeordneten Elements fallen und dort Datenattribute verwendet werden, die langsamer werden.

Trotz der Tatsache, dass ich Angular drei Jahre lang beschimpft habe, muss ich jetzt zugeben, dass es im Moment am besten darin implementiert ist. In Angular reicht es aus, einfach den Isolationsmodus zu wechseln und bei Bedarf das Shadow-DOM zu verwenden, ansonsten eine normale Emulation, um eine gute Stilisolation zu gewährleisten.

Zurück zum Spinner. Von den drei Monaten, die ich mit ihm gekämpft habe, war ich einige Zeit in einem aufregenden Geschäft tätig: der Reinigung.



Eine Klasse loading-containerist ein Implementierungsdetail eines Spinners, dh es ist eine Klasse innerhalb einer Spinner-Implementierung. Wir haben beschlossen, im Pyjama ein separates CSS basierend auf Atomic CSS zu erstellen, da CSS nicht gespeichert werden soll. Ich persönlich mag das Atomic CSS-Konzept nicht wirklich, aber wir haben das, was wir haben.

Das heißt, ich war damit beschäftigt, Stile im Code des Hauptprodukts zu bereinigen, die an Elementen hängen, die Implementierungsdetails sind. Es sieht alles sehr einfach aus - denn natürlich gibt es Tests in GitLab.

2. Tests


Tests in GitLab decken den gesamten Code ab und bieten Zuverlässigkeit. Damit ist die Pipeline in 98 Minuten fertig.



40% der Zeit von öffentlichen Läufern auf GitLab.com GitLab sammelt GitLab selbst, da die Pipeline zu jeder Zusammenführungsanforderung geht.

Ich war sehr inspiriert: Ich habe endlich ein Projekt bekommen, bei dem alles in Tests behandelt wird! Die Abdeckung des Backend-Codes liegt nahe bei 100%, und der Front-End-Code zum Zeitpunkt meiner Ankunft war zu 89,3% abgedeckt .

Leider stellte sich heraus, dass der größte Teil dieser Berichterstattung Müll ist, weil:

  • bricht zusammen, wenn Änderungen vorgenommen werden, die sich nicht auf die Komponenten beziehen;
  • Bricht nicht, wenn Änderungen vorgenommen werden.

Ich werde mit Beispielen erklären. Wir haben Jest genommen, weil wir dachten, dass er uns in bestimmten Situationen erlauben würde, keine Behauptungen zu schreiben, sondern Schnappschüsse zu verwenden. Das Problem ist, dass Vue Test Utils Requisiten einfach in HTML ausgibt, wenn Sie Jest nicht konfiguriert und den richtigen Serializer hinzugefügt haben. Dann stellt sich beispielsweise heraus, dass Requisiten mit dem Namensbenutzer Requisiten in den Parametern mit den Namensdaten hatten, an die das Objektobjekt übergeben wurde. Änderungen im Format der übertragenen Daten führen nicht zu einem Fehler des Snapshots.

Ruby-Entwickler sind es gewohnt, Tests durchzuführen, die grob gesagt alle Methoden abdecken.
Wenn wir Tests für Vue- oder React-Komponenten durchführen, müssen wir testen, wie sich die öffentliche API verhält.
Daher hatten wir umfangreiche Tests mit berechneten Eigenschaften, die in einigen Szenarien nicht verwendet wurden, in anderen war es jedoch physikalisch unmöglich, den Status zu erreichen, in dem diese berechneten Eigenschaften aufgerufen wurden. Besonderer Dank geht an Vue, in dem die Vorlagen Zeichenfolgen sind, sodass Sie die Testabdeckung der Vorlage nicht berechnen können. In Vue 3 werden Quellkarten angezeigt und die Möglichkeit, sie zu beheben, wird jedoch nicht in Kürze verfügbar sein.

Glücklicherweise gibt es eine einfache Fähigkeit, mit der Sie das Erbe effektiv umgestalten können. Dies ist die Fähigkeit, den sogenannten Pinning-Test in der großen Testwelt zu schreiben.

Pinning-Test


Dies ist ein Test, der versucht, das Verhalten zu erfassen, das Sie umgestalten. Bitte beachten Sie, dass der Pinning-Test höchstwahrscheinlich nicht in das Repository übernommen wird. Das heißt, Sie schreiben durch alle Arten von Verfeinerungen, beispielsweise mithilfe der Staging-Umgebung, selbst einen Test, der beschreibt, wie Ihre Komponente gerendert wird. Nach dem Refactoring sollte der Pinning-Test entweder denselben HTML-Code generieren, und dies ist höchstwahrscheinlich ein gutes Zeichen, oder Sie sollten verstehen, welche Änderungen aufgetreten sind.

Ich werde ein Beispiel aus dem Leben geben. Vor einigen Monaten habe ich eine Überprüfung der Zusammenführungsanforderung durchgeführt und eine Dropdown-Liste überarbeitet. Der alte Kontext ist folgender: Um die Zweige eines Freundes durch einen Bindestrich in der Dropdown-Liste voneinander zu trennen, wurde früher einfach die Textzeichenfolge „Teiler“ übergeben. Wenn Ihr Zweig also Teiler genannt wurde, haben Sie kein Glück. Während des Refactorings tauschte eine Person zwei Klassen in einem HTML-Knoten aus. Dieser ging in die Produktion und ruinierte ihn. Fairerweise natürlich nicht ganz die Produktion, sondern die Inszenierung, aber trotzdem.

Als wir mit dem Schreiben solcher Tests begannen, stellten wir fest, dass die Tests trotz des coolen Indikators für die Testabdeckung falsch geschrieben wurden. Denn erstens hatten wir Tests für Karma, das heißt für alte. Zweitens haben fast alle Tests Annahmen über die Interna der Komponente getroffen. Das heißt, sie gaben vor, Komponententests zu sein, und arbeiteten im Wesentlichen wie Ende-zu-Ende. Dabei wurde überprüft, ob ein bestimmtes Tag mit einer bestimmten Klasse gerendert wurde, anstatt zu überprüfen, ob eine bestimmte Komponente mit bestimmten Requisiten gerendert wurde. Verstehen Sie den Unterschied: Klassen sind Komponenten?

Als Ergebnis meiner 18 Zusammenführungsanfragen mit Refactoring-Tests für insgesamt 8-9.000 Zeilen stellte sich heraus, dass das gesamte Änderungsprotokoll ungefähr 20.000 betrug, da 11.000 gekürzt wurden.



Gleichzeitig habe ich alle diese Tests formell überarbeitet, um eines zu behaupten: um Aussagen über Spinnerklassen zu entfernen und stattdessen zu überprüfen, ob der Spinner mit den richtigen Requisiten dort gerendert ist.

Auf den ersten Blick ist dies ein undankbarer Job. Das Umschreiben von Tests für die richtige Architektur war jedoch recht einfach an das Unternehmen zu verkaufen. GitLab ist ein kommerziell profitables Produkt. Wenn Sie dem Produktmanager mitteilen, dass Sie drei Iterationen benötigen, um 20 Tests neu zu schreiben, raten Sie natürlich, wohin Sie gesendet werden. Eine andere Sache: „Ich benötige drei Iterationen, um den Test neu zu schreiben. Auf diese Weise können wir Spinner effizienter einführen und die zukünftige Implementierung neuer Elemente des Designsystems beschleunigen. “ Und hier kommen wir zum Wichtigen.

3. Widerstand


Es gibt eine weitere Funktion, auf die mehr meiner Spinner im GitLab-Designsystem warten - dies sind normale SVG-Symbole.


Wir haben vom Designer gezeichnete Symbole, die im Hauptprojekt verwendet werden, aber sie befinden sich nicht im Designsystem, da GitLab eine schwierige Kindheit hat. Zum Beispiel wird CSS 2019 nicht über Webpack, sondern über Sprockets gesammelt - dies ist Pipeline Ruby, da wir dasselbe CSS im Backend und Frontend wiederverwenden müssen. Aus diesem Grund müssen Symbole auf unterschiedliche Weise mit verschiedenen Projekten verbunden werden. Daher hat jemand die Hauptcodebasis drei Monate lang überarbeitet, damit Sie die Symbole aus dem Entwurfssystem mit verwandten Projekten verbinden können.

Hier gibt es einen wichtigen Punkt, dem Sie unweigerlich begegnen werden. Refactoring ist ein Prozess der kontinuierlichen Verbesserung. Aber früher oder später muss man aufhören.
Es ist absolut normal, aufzuhören, das Refactoring nicht abzuschließen, sondern konkrete messbare Verbesserungen zu erzielen.
Wenn Sie jedoch an einem Legacy-Projekt arbeiten, werden Sie unweigerlich auf Leute stoßen, die dies tun.

Das bedeutet, dass sie auf die alte Art schreiben, weil sie so daran gewöhnt sind. Zum Beispiel sagen unsere Unterstützer: "Ich möchte dies nicht Ihren Scherz beibringen. Ich habe drei Jahre lang Tests für Karma geschrieben. Ich muss neue Funktionen hinzufügen. Da diese ohne Tests keine Funktionen annehmen, ist hier ein Test für Karma. "

Ihre Aufgabe ist es, dem so weit wie möglich zu widerstehen. Dies ist relativ leicht zu bekämpfen, aber es gibt eine noch größere Sünde als diese. Manchmal stößt man beim Refactoring auf ein Problem, und es besteht der Wunsch, generell beiseite zu gehen.

Das heißt, eine neue Krücke zu ersetzen, nur weil es aus bestimmten Gründen nicht möglich ist, das Refactoring zu beenden. Wenn wir beispielsweise Probleme haben, Symbole in die Hauptcodebasis zu integrieren, können wir eine Dienstprogrammklasse belassen, die aus dem globalen Anwendungs-CSS abgerufen wird. Formal wird die Geschäftsaufgabe gelöst, aber in der Praxis wie in der Geschichte der Lernean Hydra: Es gab 8 Fehler, 4 behoben, 13 übrig.

Refactoring, wie die Reparatur eines Hauses - es ist unmöglich zu beenden, Sie können es nur stoppen.
Die ersten 80% des Refactorings dauern 20% der Zeit, die restlichen 80% des Refactorings (einfach so) dauern weitere 80% der Zeit.
Es ist wichtig, während des Refactoring-Prozesses keine neuen Hacks einzuführen. Glauben Sie mir, während des Entwicklungsprozesses werden sie selbst erscheinen.

4. Werkzeuge


Glücklicherweise hat GitLab bereits vor meiner Ankunft den richtigen Weg eingeschlagen, um gute Tools einzuführen: Prettier, Vue Test Utils, Jest. Obwohl Prettier schief umgesetzt hat.

Ich werde erklären, worum es geht. Während ich in der Vergangenheit herausgefunden habe, was und warum dies so ist, stießen 80% meiner Suchanfragen auf ein Commit von 37.000 Zeilen Prettify-Code. Es war fast unmöglich, den Verlauf zu verwenden, und ich musste das Plug-In für VS-Code so konfigurieren, dass dieses Commit bei der Suche nach dem Änderungsverlauf ausgeschlossen wird.

Sicher, Werkzeuge sind wichtig, aber Sie müssen sie sorgfältig auswählen. Zum Beispiel haben wir Vue und Vue hat ein gutes Testwerkzeug - Vue Test Utils. Aber wenn Vue 2 vor 2-3 Jahren veröffentlicht wurde, sind die Vue Test Utils immer noch nicht aus der Beta herausgekommen. Laut Insiderinformationen schreibt der einzige Entwickler von Vue Test Utils derzeit nicht über Vue.

Bei der Auswahl der Werkzeuge spielen Sie mit dem Schicksal und versuchen wirklich zu gewinnen.

GitLab hatte eine Kindheitsverletzung mit CoffeeScript. Aus diesem Grund ist es unmöglich, auch nur die theoretische Idee des Schreibens in TypeScript in GitLab voranzutreiben. Alles gliedert sich in ein einfaches Argument: Wird es nicht dasselbe sein wie bei CoffeeScript, wenn die Sprache, die in JavaScript kompiliert wird, gestorben ist?
Versuchen Sie bei der Auswahl der Werkzeuge, dass das Werkzeug ausgetauscht oder im Extremfall unabhängig gewartet werden kann.
Wir bei GitLab verwenden eine coole Sache namens Danger.

Dies ist ein echter Screenshot ihrer Website im Jahr 2019. Kollegen sagten jedoch, dass die Website im Jahr 2019 tatsächlich wie alles aussehen könnte.

Gefahr ist ein Bot, der einen Zwischenzustand zwischen dem Linter in Ihrem CI und den schriftlichen Richtlinien einnimmt. Dieser Bot kann erweitert werden und es wird kommen, um Anfrage zu ziehen oder, wie sie bei uns richtig genannt werden, Anfrage zusammenzuführen und Kommentare zu hinterlassen wie:
  • "Diese Datei enthält einen ESlint-Deaktivierungskommentar. Korrigieren Sie ihn."
  • „Diese Datei wurde früher von dieser Person regiert. Vielleicht müssen Sie eine Bewertung abgeben. “

Meiner Meinung nach ist dies ein sehr guter, wichtiger und erweiterbarer Rahmen für die Überwachung des Status der Codebasis.

5. Abstraktion


Ich werde mit einem Beispiel beginnen. Vor einigen Monaten sah ich die Nachricht: „GitHub hat jQuery losgeworden. Wir haben einen langen, schwierigen Weg zurückgelegt und verwenden jQuery nicht mehr. “ Natürlich dachte ich, dass wir auch jQuery in GitLab loswerden müssen.



Eine schnelle Suche ergab, dass jQuery in 300 Dateien verwendet wird. Es sieht beängstigend aus, aber nichts - die Augen haben Angst, die Hände tun es. Aber nein! jQuery ist ein integraler Bestandteil der GitLab-Codebasis, da wir Bootstrap haben.

Bootstrap wurde ursprünglich in jQuery geschrieben. Dies bedeutet, dass dies ein jQuery-Ereignis ist, wenn Sie beispielsweise das Dropdown-Eröffnungsereignis in Bootstrap abfangen müssen. Sie können es nicht nativ abfangen.

Dies ist das erste, was Sie abstrahieren sollten, wenn Sie mit Legacy-Code arbeiten. Wenn Sie jQuery haben, das Sie nicht wegwerfen können, schreiben Sie Ihren eigenen Event Emitter, der sich in der Arbeit mit jQuery-Ereignissen versteckt.

Wenn eine glänzende Zukunft kommt, können wir jQuery entfernen, aber im Moment müssen Sie sich leider auf den Govnokod konzentrieren. In einem regulären Legacy-Projekt wird es gleichmäßig im Code verteilt. Sammeln Sie es in Engpässen, die mit den Markierungen „Nicht ohne Chemikalienschutzanzug betreten“ gekennzeichnet sind.

6. Metriken


Sie können nichts tun, dessen Ergebnis nicht gemessen werden kann. Bei GitLab messen wir alles, was wir tun, um objektiv zu wissen, dass der Code besser funktioniert.



Zum Beispiel haben wir einen Migrationsplan von Karma-Tests (blau) zu Jest (grün):

Sie sehen, dass es schrittweise Fortschritte gibt. Und wir haben viele solcher Zeitpläne. Es ist jedoch wichtig zu verstehen, dass nicht immer alles gut endet.

Ich werde noch ein Beispiel geben (die Demo im Bericht beginnt ab diesem Moment).



Hier ist die übliche Schnittstelle für Zusammenführungsanforderungen in der GitLab-Produktion. Natürlich können wir Dateien reduzieren, auf den Header klicken und die Datei beginnt zu reduzieren.

Was denken Sie, wie lange dauert es, eine Datei mit 50 Zeilen zu reduzieren, während der Computer mit dem Core i7 der achten Generation für maximale Leistung verdreht ist? Wie lange dauert die Bereitstellung?

Die Zeit, die die Datei zum Reduzieren benötigt, liegt zwischen 7 und 15 Sekunden. Die Bereitstellung erfolgt sofort. Vor dem Refactoring arbeiteten beide gleich schnell.

Deshalb ist es sehr wichtig, Metriken zu haben.

Ich werde Ihnen sagen, was hier passiert. Dies ist Vue, sein Reaktivitätssystem verfolgt den Wert: Wenn es sich ändert, werden alle Abhängigkeiten aufgerufen, die von diesem Wert abhängen. Jede Zeile ist eine Vue-Komponente, die aus vielen Dingen besteht, da Sie Kommentare in eine Zeile einfügen können, Kommentare dynamisch vom Server geladen werden können usw. All dies wird im Vue-Store abonniert, der auch eine Vue-Komponente ist.

Wenn Sie die Zusammenführungsanforderung schließen, müssen beispielsweise alle 20.000 Geschäftsabonnements aktualisiert werden, wenn das Geschäft aktualisiert wird. Wenn die Zeile gelöscht wird, muss sie aus den Abhängigkeiten entfernt werden. Und dann einfache Mathematik: Sie müssen sich ein Array von 20.000 Elementen ansehen, um diejenigen zu finden, die entfernt werden müssen. Angenommen, es gibt 500 solcher Zeilen, und jede Zeile besteht aus mehreren Komponenten. Das Ergebnis ist eine mathematische Operation O (N), dh O (20.000) * 500. JavaScript wurde die ganze Zeit ausgeführt.

Die Bereitstellung erfolgt sofort, da das Hinzufügen einer Abhängigkeit nur ein Push für das Array ist, d. H. mathematische Operation O (1).

Manchmal verschlechtert die Verbesserung der Codequalität die Leistung und andere Metriken. Es ist sehr wichtig, sie zu messen.

Zusammenfassend: Isolieren Sie fehlerhaften Code und verfolgen Sie die Metriken.

legacy — . , – TechLead Conf — , . – , legacy Python, PHP.

, ++, , FrontendConf. .

All Articles