Die Lokalisierung einer dynamischen Anwendung wie Sprout Social in mehrere Sprachen ist ein komplexes Unterfangen. Die Übersetzung des in der Bewerbung erscheinenden Textes ist nur die eine Hälfte der Geschichte. Dazu gehört auch, unsere Anwendung so zu entwickeln, dass es einfach ist, diesen Text zu extrahieren und gegen die Übersetzungen auszutauschen. Bei Sprout stützen wir uns bei Übersetzungen auf Drittanbieter. Aber wir benötigen immer noch Tools, um Übersetzungsanfragen zu extrahieren, zu bündeln und an diese Anbieter zu übermitteln und die Übersetzungen dann den Endbenutzern bereitzustellen und bereitzustellen.



Das Sprout-Engineering-Team kam jahrelang mit einer maßgeschneiderten Lokalisierungslösung aus, da Open-Source-Lösungen noch ausgereift waren. Damit konnten wir unsere größten Kunden in unseren unterstützten Sprachen bedienen, es fehlten uns jedoch einige nützliche Funktionen. In diesem Artikel werde ich unser neues Lokalisierungssystem skizzieren, wie es die kompliziertesten Lokalisierungsszenarien bewältigt und wie wir diese Änderungen schrittweise in der gesamten Web-Engineering-Organisation eingeführt haben.



Unser altes System

Um unser neues Lokalisierungssystem zu verstehen, müssen Sie zunächst verstehen, wie unser altes System funktionierte und in welchen Bereichen wir es verbessern könnten.

Nachrichtensyntax

Bei der Anwendungslokalisierung wird der für den Endbenutzer sichtbare Text in Zeichenfolgeneinheiten, sogenannte Nachrichten, abstrahiert. Diese Nachrichten werden extrahiert und an Übersetzer weitergeleitet. Indem wir diese Zeichenfolgen abstrahieren, können wir sie je nach der bevorzugten Sprache des Endbenutzers problemlos austauschen.

Diese Nachrichten können einfache statische Zeichenfolgen wie „Hallo, Welt“ sein oder Platzhalter wie „Hallo, {Name}“ oder Rich-Text-Formatierung wie „Hallo, Welt“ haben. Da diese Funktionen in Zeichenfolgen serialisiert werden müssen, benötigen Sie eine Syntax, die sowohl die Übersetzer als auch der Anwendungscode verstehen, um den Text richtig zu übersetzen und darzustellen.

Was die Verwendung unseres alten Lokalisierungssystems unter anderem dadurch erschwerte, dass wir unsere eigene Syntax entwickelten und einen hausgemachten „Parser“ für diese Syntax verwalteten. Die Pflege dieses Codes war zeitaufwändig und die Syntax war ziemlich minimal. Wir wollten zusätzliche Funktionen, um komplexere Nachrichten darzustellen.

Beispiel: In der Sprout-Anwendung benötigen wir eine Möglichkeit, „Sie haben X Beiträge“ darzustellen, wobei X ein dynamischer numerischer Wert ist.



Betrachten Sie den Pluralfall: „Sie haben 5 Beiträge “. Betrachten Sie den Singularfall: „Sie haben 1 Post “. Betrachten Sie den Fall „0“. Betrachten Sie Sprachen, die möglicherweise eine Grammatik für den Fall „1“ haben, wie Chinesisch und Japanisch. Betrachten Sie Sprachen, die über eine Grammatik für den Fall verfügen, dass X eine „große Zahl“ ist, wie Arabisch, Polnisch und Russisch.

Nachrichtenverwaltung

Wir haben Nachrichten, die wir an Übersetzer senden und in unserer Anwendung austauschen können. Unsere Anwendung benötigt eine Möglichkeit, diese Nachrichten zu speichern und sie unseren Endbenutzern bereitzustellen.

Unser altes System speicherte alle unsere Nachrichten in JSON-Dateien (wir nannten sie „lang-Dateien“), die manuell verwaltet wurden. Wir haben auf die Nachrichten in diesen Dateien verwiesen, indem wir IDs in unserem Quell-Javascript-Code verwendet haben. Wenn ein Benutzer die Anwendung auf Spanisch wollte, stellten wir unsere spanischen Sprachdateien bereit und dann renderte Javascript die entsprechende spanische Nachricht mithilfe der ID.



Aus Leistungsgründen haben wir versucht, nur die Benutzernachrichten bereitzustellen, die sich auf dieser Seite befanden, daher hatten wir separate Langdateien für die verschiedenen Seiten der Anwendung. Dies war ein gültiges System, aber als unser Team und unsere Anwendung skalierten, bedeutete dies mehr manuelle Entwicklerzeit für die Erstellung und Verwaltung dieser IDs und Langdateien.

  Screenshot von JavaScript, das zuvor zum manuellen Verwalten von Nachrichten und Übersetzungen in Sprout verwendet wurde's codebase.

Um der Anwendung eine neue Nachricht hinzuzufügen, mussten Entwickler sie manuell zur richtigen Lang-Datei mit einer eindeutigen ID hinzufügen, um auf diese Nachricht zu verweisen. Manchmal kam es zu Problemen mit ID-Kollisionen und ID-Tippfehlern, die dazu führten, dass die Sprache in der Anwendung fehlte. Das Hinzufügen von Text zur Webanwendung fühlte sich mühsam an, da zahlreiche Schritte nicht intuitiv waren.


316 Nummer Bedeutung

Unsere neue Lösung

Webingenieure aus der gesamten Produktorganisation waren sich dieser Mängel bewusst und gründeten eine Lokalisierungsarbeitsgruppe, um eine Lösung zu entwickeln. Wir trafen uns regelmäßig zum Brainstorming. Nach einem eingehenden Rechercheprozess haben wir uns entschieden, die Sprout-Anwendung von unserem hausgemachten Lokalisierungssystem auf die Verwendung von FormatJS zu migrieren reagieren-intl Bibliothek und bauen darauf eine Infrastruktur für die Verwaltung unserer Nachrichten auf. React-intl war die funktionsreichste und beliebteste Open-Source-Lokalisierungsbibliothek im Javascript-Ökosystem und ließ sich gut in unsere Codebasis integrieren.

Nachrichtensyntax

Wir wollten eine robustere Lösung und nicht etwas von Grund auf neu erstellen. Wir haben das übernommen Syntax der ICU-Nachricht , eine standardisierte Syntax, die in Java-, PHP- und C-Anwendungen verwendet wird und die Komplexität dynamischer Anwendungsnachrichten erfasst. Der reagieren-intl Die Bibliothek unterstützt auch das Parsen und Rendern von ICU-Nachrichtensyntaxnachrichten.

  Ein Gegenüberstellungsbeispiel dafür, wie die ICU-Nachrichtensyntax mehrere Fälle erfasst. Auf der linken Seite ist die Nachricht auf Englisch zu sehen, bevor sie ins Russische übersetzt wird. Rechts ist die ins Russische übersetzte Nachricht. Beachten Sie, dass die Übersetzer bei der Konvertierung dieser Nachricht in andere Sprachen nach Bedarf Groß- und Kleinschreibung hinzufügen und entfernen können, um die Sprache ordnungsgemäß zu unterstützen. Die russische Übersetzung dieser Nachricht fügt „wenige“ und „viele“ Fälle hinzu.

Dies ist ein Beispiel dafür, wie die ICU-Nachrichtensyntax mehrere Fälle erfasst. Dies ist die Nachricht auf Englisch und Russisch. Beachten Sie, dass die Übersetzer bei der Konvertierung dieser Nachricht in andere Sprachen nach Bedarf Groß- und Kleinschreibung hinzufügen und entfernen können, um die Sprache ordnungsgemäß zu unterstützen. Die russische Übersetzung dieser Nachricht fügt „wenige“ und „viele“ Fälle hinzu.

Die ICU-Nachrichtensyntax wurde von vielen Anwendungen in unzähligen Sprachen kampferprobt. Wir konnten darauf vertrauen, dass es unsere anspruchsvollen Kundenbedürfnisse erfüllen konnte und dass es viele Lösungen und/oder Bildungsressourcen für alle Lokalisierungsfragen gab, auf die wir stießen.

Nachrichtenverwaltung

Wir haben mit den von FormatJS bereitgestellten Tools ein System entwickelt, das den Prozess des Hinzufügens, Entfernens und Speicherns von Nachrichten automatisiert. Dies brachte einige philosophische Änderungen in der Art und Weise mit sich, wie wir an die Speicherung und Referenzierung von Nachrichten herangingen.

Eine wesentliche Änderung gegenüber unserem alten System, die FormatJS empfiehlt, war die Verwendung unseres UI-Codes als Quelle der Wahrheit für Nachrichten. In unserem vorherigen System befanden sich die Quelle der Nachrichten und die Verwendung der Nachrichten an zwei verschiedenen Orten, was bedeutete, dass wir sie synchron halten mussten. Unser neues System behält die Nachrichtenquellen beim Rest des UI-Codes bei. Wir müssen lediglich ein Skript ausführen, das alle Nachrichten aus den UI-Dateien extrahiert, um unsere Lang-Dateien zu generieren, und der Nachrichteninhalt wird mithilfe einer Hash-Funktion zu eindeutigen IDs.

  Screenshot von JavaScript, das zuvor zur automatischen Verwaltung von Nachrichten und Übersetzungen in Sprout verwendet wurde's codebase.

Diese Änderung ordnet die Nachrichten zusammen mit dem UI-Code ein und hatte mehrere Vorteile:

  • Besser lesbar: In unserem UI-Code gibt es keine IDs mehr, die für Roboter konzipiert sind. Jetzt können wir die englischen Nachrichten im UI-Code lesen und verstehen, welchen Text der Benutzer sehen wird.
  • Nicht-manuelle IDs: Diese IDs, die früher nur von Maschinen verwendet wurden, werden jetzt von Maschinen generiert und sind per Definition eindeutig pro Nachricht.
  • Keine manuell verwalteten Langdateien: Entwickler sollten diese Lang-Dateien nicht berühren müssen. Unsere Skripte verwalten das Hinzufügen und Löschen der Nachrichten.

Wie sind wir migriert?

Aber wie haben wir unser gesamtes Web-Engineering-Team und unsere Codebasis auf dieses neue System migriert? Wir haben dies in vier Meilensteine ​​unterteilt: Pilotierung des neuen Systems, Schulung unseres Teams, Abschaffung des alten Systems und Migration auf unsere neue Lösung.

Pilotierung des neuen Systems

Die Arbeitsgruppe testete das neue System in bestimmten Abschnitten der Anwendung, um einen Eindruck von seinen Best Practices und dem gesamten Migrationsumfang zu bekommen. Dadurch wurde das neue System auf der Clientseite (Polyfüllungen usw.) und auf der Build-Seite der Anwendung eingerichtet. Dies ermöglichte es uns, die Entwicklererfahrung zu verbessern und das Risiko zu mindern.

Ausbildung

Wir haben das, was wir aus dem Pilotprojekt gelernt haben, genutzt, um das gesamte Web-Engineering-Team zu schulen. Wir haben eine FAQ und andere pädagogische Dokumentationen und Präsentationen entwickelt, um Entwicklern bei der Verwendung der neuen Bibliothek zu helfen. Dieser Schritt wird leicht unterschätzt, aber dieser Teil einer Migration ist äußerst wichtig. Es spielt keine Rolle, wie gut Ihr neues System ist – die Leute müssen wissen, wie und warum sie es nutzen sollten.

Wir haben auch ein Botschafterprogramm entwickelt, bei dem jedes Web-Feature-Team bei Sprout einen ernannten Lokalisierungsbotschafter hatte, der dafür verantwortlich war, sein Team über das neue System zu informieren und der Arbeitsgruppe Probleme oder Schwachstellen zu melden.

Dies ermöglichte es uns, die Bildungsverantwortung zu delegieren und spezifische Probleme für einzelne Teams zu identifizieren.

Das alte System wird abgelehnt

Nachdem wir von der Entwicklererfahrung, dem gemeinsamen Wissen und dem Skalierungspotenzial des neuen Systems überzeugt waren, haben wir das alte System eingestellt. Wir haben einige benutzerdefinierte Eslint-Regeln erstellt und das Linting-Tool verwendet. Schiene , um die Nutzung des alten Systems zu blockieren und gleichzeitig bestehende Nutzungen zuzulassen. Von diesem Zeitpunkt an wurde von Webentwicklern erwartet, dass sie das neue System verwenden, wenn sie neuen Code schreiben.

Migration auf unser neues System

Mit Vertrauen in unser neues System und einer festen Anzahl alter Nutzungen begannen wir mit der Migration.

Viele Verwendungen hatten im neuen System eine Eins-zu-eins-Entsprechung. Wo diese Äquivalente vorhanden sind, konnten wir die Migration automatisieren, indem wir einen Code-Mod mit geschrieben haben jscodeshift . Wir konnten den Code-Mod iterativ über Abschnitte der Codebasis laufen lassen und dabei lernen und Probleme beheben. Es gab nur noch wenige Randfälle, die sich nicht einfach per Code modifizieren ließen, so dass wir uns wohl fühlten, sie manuell zu beheben.


Triple 5 Bedeutung

Ausrollen

Warum haben wir uns für einen so iterativen Ansatz entschieden, anstatt zu versuchen, alles auf einmal zu migrieren? Die Verwendung eines iterativen Ansatzes ist Teil der Ingenieurskultur von Sprout und wir glauben daran, ständig zu lernen und uns zu verbessern.

Indem wir die Migration auf diese Weise angingen, konnten wir dabei lernen und Probleme in Echtzeit anpassen und beheben. Wir könnten die Änderungen auch rückgängig machen, wenn die Migration begann, die Anwendungsentwicklung zu blockieren. Unser iterativer Ansatz ermöglichte es uns, Fortschritte zu machen, während wir an anderen Initiativen arbeiteten, und befähigte uns, größere Änderungen mit einer kleineren Gruppe zu markieren, bevor wir sie allen zur Verfügung stellten. Für die Entwicklung interner Entwicklertools gelten dieselben Prinzipien der Funktionsentwicklung für eine Anwendung.

Erkenntnisse und Erkenntnisse

Die Neugestaltung unseres Lokalisierungssystems war ein gewaltiges Unterfangen für die gesamte Web-Engineering-Organisation. Mein Rat an andere, die vor ähnlichen Projekten oder Herausforderungen stehen, wäre:

  • Nutzen Sie weit verbreitete Standards: Warum eine benutzerdefinierte Nachrichtensyntax erstellen, wenn Ingenieure, die jahrelang über diesen Problembereich nachgedacht haben, bereits eine Nachrichtensyntax für die Intensivstation entwickelt haben?
  • Erwägen Sie die Zusammenstellung verwandter Elemente: Dadurch wird das Hinzufügen, Ändern und Löschen erheblich vereinfacht.
  • Nutzen Sie einen iterativen Rollout: Gestalten Sie die Einführung Ihrer Änderung so, dass Sie unterwegs lernen können. Sie können nicht alles vorhersehen, also planen Sie Rückgriffsmöglichkeiten ein.
  • Teilen Sie Ihre Erkenntnisse: Bildung ist die halbe Einführung. Es spielt keine Rolle, wie gut Ihr neues System ist, wenn die Leute nicht wissen, wie man es benutzt oder warum es besser ist.

Weitere Informationen zur Ingenieurskultur von Sprout finden Sie in unserem Karriereseite Heute.

Teile Mit Deinen Freunden: