
Dies ist der zweite Teil des Artikels über das Erstellen eines Tools, mit dem alle in einer Skizzendatei platzierten Symbole exportiert werden können: in verschiedenen Formaten für verschiedene Plattformen mit der Möglichkeit, jedes Symbol A / B zu testen.
Sie können den ersten Teil
über den Link lesen.

Beim letzten Mal haben wir Skizzendateien vorbereitet, die alle Symbole in den richtigen Stilen und mit den richtigen Namen enthalten. Es ist an der Zeit, Code zu schreiben.
Es genügt zu sagen, dass wir Versuch und Irrtum durchlaufen haben. Nachdem unser Teamleiter
Nihil Verma , der den Grundstein für das Skript gelegt hatte, den wichtigsten Quellcode entwickelt hatte, startete ich einen Prozess, der mindestens drei Phasen des Refactorings und viele Änderungen erforderte. Aus diesem Grund werde ich nicht auf die Details der Erstellung des Skripts eingehen und mich darauf konzentrieren, wie es heute in seiner endgültigen Form funktioniert.
Skript erstellen
Das auf Node.js geschriebene Build-Skript ist in seiner Arbeit ziemlich einfach: Durch Importieren von Abhängigkeiten, Deklarieren einer Liste von Sketch-Dateien zur Verarbeitung (es ist eine Liste von Marken, von denen jede eine Liste von Dateien enthält) und Sicherstellen, dass Sketch auf dem Client installiert ist Das Skript verarbeitet die Marken nacheinander und führt mit jeder eine Reihe von Aktionen aus.
- Nimmt Design-Token, die für Marken geeignet sind (wir benötigen Farbwerte).
- Klont markenassoziierte Skizzendateien, entpackt sie, extrahiert interne JSON-Dateien und verarbeitet einige ihrer internen Werte (dazu später mehr).
- Liest die erforderlichen Metadaten aus diesen JSON-Dateien ( document.json , meta.json und pages / pageUniqueID.json ). Wir sind an Listen gängiger Stile und Ressourcen / Symbole interessiert, die in Dateien enthalten sind.
- Nach einigen weiteren Manipulationen mit JSON-Dateien wird das Archiv neu erstellt und mithilfe von Skizzendateien (geklont und aktualisiert) die endgültigen Ausgabedateien für drei Plattformen (iOS, Android, Mobile Web) exportiert und erstellt.
Die relevanten Teile des Build-Skripts finden Sie hier:
// ... modules imports here const SKETCH_FILES = { badoo: ['icons_common'], blendr: ['icons_common', 'icons_blendr'], fiesta: ['icons_common', 'icons_fiesta'], hotornot: ['icons_common', 'icons_hotornot'], }; const SKETCH_FOLDER_PATH = path.resolve(__dirname, '../src/'); const SKETCH_TEMP_PATH = path.resolve(SKETCH_FOLDER_PATH, 'tmp'); const DESTINATION_PATH = path.resolve(__dirname, '../dist'); console.log('Build started...'); if (sketchtool.check()) { console.log(`Processing Sketch file via ${sketchtool.version()}`); build(); } else { console.info('You need Sketch installed to run this script'); process.exit(1); } // ---------------------------------------- function build() { // be sure to start with a blank slate del.sync([SKETCH_TEMP_PATH, DESTINATION_PATH]); // process all the brands declared in the list of Sketch files Object.keys(SKETCH_FILES).forEach(async (brand) => { // get the design tokens for the brand const brandTokens = getDesignTokens(brand); // prepare the Sketch files (unzipped) and get a list of them const sketchUnzipFolders = await prepareSketchFiles({ brand, sketchFileNames: SKETCH_FILES[brand], sketchFolder: SKETCH_FOLDER_PATH, sketchTempFolder: SKETCH_TEMP_PATH }); // get the Sketch metadata const sketchMetadata = getSketchMetadata(sketchUnzipFolders); const sketchDataSharedStyles = sketchMetadata.sharedStyles; const sketchDataAssets = sketchMetadata.assetsMetadata; generateAssetsPDF({ platform: 'ios', brand, brandTokens, sketchDataSharedStyles, sketchDataAssets }); generateAssetsSVGDynamicMobileWeb({ platform: 'mw', brand, brandTokens, sketchDataSharedStyles, sketchDataAssets }); generateAssetsVectorDrawableDynamicAndroid({ platform: 'android', brand, brandTokens, sketchDataSharedStyles, sketchDataAssets }); }); }
Tatsächlich ist der Pipeline-Code viel komplizierter. Der Grund für diese Komplexität liegt in den Funktionen
prepareSketchFiles
,
getSketchMetadata
und
generateAssets[format][platform]
. Im Folgenden werde ich versuchen, sie genauer zu beschreiben.
Skizzendateien vorbereiten
Der erste Schritt im Assemblierungsprozess ist die Erstellung von Skizzendateien, die später zum Exportieren von Ressourcen für verschiedene Plattformen verwendet werden.
Dateien, die einer bestimmten Marke zugeordnet sind (im Fall von Blendr sind dies beispielsweise
icons_common.sketch- und
icons_blendr.sketch-Dateien ), werden in einen temporären Ordner (genauer gesagt in einen Unterordner, der nach der verarbeiteten Marke benannt ist) geklont und entpackt.
Dann werden die JSON-Dateien verarbeitet. Dem Namen der Ressourcen, die A / B-Tests unterzogen werden, wird ein Präfix hinzugefügt. Beim Exportieren werden sie daher in einem Unterordner mit einem vordefinierten Namen (entsprechend dem eindeutigen Namen des Experiments) gespeichert.
Anhand des Namens der Seite, auf der sie gespeichert ist, können Sie nachvollziehen, ob eine Ressource einem A / B-Test unterzogen wird. Wenn dies der
Fall ist, enthält der Name das Präfix "
XP_ ".

Im obigen Beispiel werden die exportierten Ressourcen in einem Unterordner von "
this__is_an_experiment " mit einem Dateinamen der Form "
icon-name [variantenname] .ext "
gespeichert .
Skizzenmetadaten lesen
Der zweite wichtige Schritt besteht darin, alle erforderlichen Metadaten aus Skizzendateien bzw. internen JSON-Dateien zu extrahieren. Wie wir oben gesehen haben, sind dies zwei Hauptdateien (
document.json und
meta.json ) und
Auslagerungsdateien (
pages / pageUniqueId.json ).
Die Datei
document.json wird verwendet, um die Liste der allgemeinen Stile
abzurufen , die unter der Eigenschaft des
layerStyles- Objekts
angezeigt werden:
{ "_class": "document", "do_objectID": "45D2DA82-B3F4-49D1-A886-9530678D71DC", "colorSpace": 1, ... "layerStyles": { "_class": "sharedStyleContainer", "objects": [ { "_class": "sharedStyle", "do_objectID": "9BC39AAD-CDE6-4698-8EA5-689C3C942DB4", "name": "features/feature-like", "value": { "_class": "style", "fills": [ { "_class": "fill", "isEnabled": true, "color": { "_class": "color", "alpha": 1, "blue": 0.10588235408067703, "green": 0.4000000059604645, "red": 1 }, "fillType": 0, "noiseIndex": 0, "noiseIntensity": 0, "patternFillType": 1, "patternTileScale": 1 } ], "blur": {...}, "startMarkerType": 0, "endMarkerType": 0, "miterLimit": 10, "windingRule": 1 } }, ...
Wir speichern grundlegende Informationen zu jedem Stil in einem Objekt im Schlüsselwertformat. Es wird später verwendet, wenn wir den Namen des Stils basierend auf einer eindeutigen ID
do_objectID
(Eigenschaft
do_objectID
in Sketch):
const parsedSharedStyles = {}; parsedDocument.layerStyles.objects.forEach((object) => { parsedSharedStyles[object.do_objectID] = { name: object.name, isFill: _.get(object, 'value.fills[0].color') !== undefined, isBorder: _.get(object, 'value.borders[0].color') !== undefined, }; });
Jetzt gehen wir zur Datei
meta.json und erhalten eine Liste der Seiten. Wir interessieren uns für ihre
unique-id
und ihren
name
:
{ "commit": "623a23f2c4848acdbb1a38c2689e571eb73eb823", "pagesAndArtboards": { "EE6BE8D9-9FAD-4976-B0D8-AB33D2B5DBB7": { "name": "Icons", "artboards": { "3275987C-CE1B-4369-B789-06366EDA4C98": { "name": "badge-feature-like" }, "C6992142-8439-45E7-A346-FC35FA01440F": { "name": "badge-feature-crush" }, ... "7F58A1C4-D624-40E3-A8C6-6AF15FD0C32D": { "name": "tabbar-livestream" } ... } }, "ACF82F4E-4B92-4BE1-A31C-DDEB2E54D761": { "name": "XP_this__is_an_experiment", "artboards": { "31A812E8-D960-499F-A10F-C2006DDAEB65": { "name": "this__is_an_experiment/tabbar-livestream[variant1]" }, "20F03053-ED77-486B-9770-32E6BA73A0B8": { "name": "this__is_an_experiment/tabbar-livestream[variant2]" }, "801E65A4-3CC6-411B-B097-B1DBD33EC6CC": { "name": "this__is_an_experiment/tabbar-livestream[control]" } } },
Dann lesen wir die JSON-Dateien, die jeder Seite im
Seitenordner entsprechen (ich wiederhole, dass die Dateinamen die Form
[pageUniqueId] .json haben ) und untersuchen die auf dieser Seite gespeicherten Ressourcen (sie sehen aus wie Ebenen). Auf diese Weise erhalten wir den
Namen , die
Breite / Höhe jedes Symbols, Skizzenmetadaten für das Symbol dieser Ebene und, wenn es sich um eine Expertenseite handelt, den Namen des
A / B-Tests und eine
Variante dieses Symbols.
Hinweis : Das page.json-Objekt verfügt über ein sehr komplexes Gerät, daher werde ich nicht weiter darauf eingehen. Wenn Sie daran interessiert sind, was sich darin befindet, empfehle ich Ihnen, eine neue leere Skizzendatei zu erstellen, Inhalte hinzuzufügen und zu speichern. Benennen Sie dann die Erweiterung in ZIP um, entpacken Sie sie und überprüfen Sie eine der Dateien im Seitenordner.
Während der Verarbeitung von Zeichenflächen erstellen wir auch eine
Liste von Experimenten (und zugehörigen Ressourcen). Wir werden es benötigen, um zu bestimmen, welche Variationen des Symbols in welchem Experiment verwendet werden - die Namen der Variationen des Symbols werden an das Basisobjekt angehängt.
Für jede markenspezifische Skizzendatei, die verarbeitet wird, erstellen wir ein
assetsMetadata
Objekt, das folgendermaßen aussieht:
{ "navigation-bar-edit": { "do_objectID": "86321895-37CE-4B3B-9AA6-6838BEDB0977", ...sketch_artboard_properties, "name": "navigation-bar-edit", "assetname": "navigation-bar-edit", "source": "icons_common", "width": 48, "height": 48 "layers": [ { "do_objectID": "A15FA03C-DEA6-4732-9F85-CA0412A57DF4", "name": "Path", ...sketch_layer_properties, "sharedStyleID": "6A3C0FEE-C8A3-4629-AC48-4FC6005796F5", "style": { ... "fills": [ { "_class": "fill", "isEnabled": true, "color": { "_class": "color", "alpha": 1, "blue": 0.8784313725490196, "green": 0.8784313725490196, "red": 0.8784313725490196 }, } ], "miterLimit": 10, "startMarkerType": 0, "windingRule": 1 }, }, ], ... }, "experiment-name/navigation-bar-edit[variant]": { "do_objectID": "00C0A829-D8ED-4E62-8346-E7EFBC04A7C7", ...sketch_artboard_properties, "name": "experiment-name/navigation-bar-edit[variant]", "assetname": "navigation-bar-edit", "source": "icons_common", "width": 48, "height": 48 ...
Wie Sie sehen können, kann im Experiment ein einzelnes Symbol (in diesem Fall die
Bearbeitung der Navigationsleiste ) vielen Ressourcen entsprechen. Gleichzeitig wird möglicherweise dasselbe Symbol unter demselben Namen in einer anderen mit der Marke verknüpften Skizzendatei angezeigt.
Dies ist sehr nützlich : Wir verwenden diesen Trick, um einen gemeinsamen Satz von Symbolen zu kompilieren und dann bestimmte Optionen entsprechend der Marke zu identifizieren. Aus diesem Grund haben wir die einer bestimmten Marke zugeordneten Skizzendateien als Array deklariert:
const SKETCH_FILES = { badoo: ['icons_common'], blendr: ['icons_common', 'icons_blendr'], fiesta: ['icons_common', 'icons_fiesta'], hotornot: ['icons_common', 'icons_hotornot'], };
In diesem Fall ist die Ordnung von grundlegender Bedeutung. Tatsächlich geben wir in der vom Skript
getSketchMetadata
Funktion
getSketchMetadata
keine
assetsMetadata
Objekte
assetsMetadata
als
assetsMetadata
. Stattdessen führen wir eine tiefe Zusammenführung von Objekten durch - wir kombinieren sie und geben ein einzelnes
assetsMetadata
Objekt zurück.
Im Allgemeinen ist dies nichts anderes als eine „logische“ Zusammenführung von Skizzendateien und ihren Ressourcen zu einer einzigen Datei. Die Logik ist jedoch nicht so einfach, wie es scheint. Hier ist ein Diagramm, das wir erstellt haben, um herauszufinden, was passiert, wenn Symbole mit demselben Namen (und möglicherweise A / B-Tests) in verschiedenen Dateien derselben Marke zugeordnet sind:

Erstellung von vorgefertigten Dateien in verschiedenen Formaten für verschiedene Plattformen
In der letzten Phase unseres Prozesses werden direkt Symboldateien in verschiedenen Formaten für verschiedene Plattformen erstellt (PDF für iOS, SVG / JSX für Web und VectorDrawable für Android).
Wie Sie an der Anzahl der Parameter erkennen können, die an die Funktionen
generateAssets[format][platform]
werden, ist dieser Teil der Pipeline der komplexeste. Hier beginnt der Prozess, sich je nach Plattform aufzulösen und zu ändern. Im Folgenden sehen Sie den logischen Verlauf des Skripts als Ganzes und wie der Teil, der sich auf die Ressourcengenerierung bezieht, in drei ähnliche, aber unterschiedliche Prozesse unterteilt ist:

Um vorgefertigte Ressourcen mit den richtigen Farben zu erstellen, die der zu verarbeitenden Marke entsprechen, müssen wir einige weitere Manipulationen mit JSON-Dateien durchführen. Wir gehen alle Ebenen durch, auf die der allgemeine Stil angewendet wird, und ersetzen die Farbwerte durch die Farben aus dem Design-Token der Marke.
Um Dateien für Android zu generieren, müssen Sie eine zusätzliche Aktion ausführen (etwas später): Wir ändern die
windingRule
jeder Ebene von
even-odd
auf
non-zero
(dies wird durch die
windingRule
Eigenschaft des JSON-Objekts gesteuert, wobei 1 "ungerade / gerade" bedeutet. und 0 ist "ungleich Null").
Nach diesen Manipulationen packen wir die JSON-Dateien wieder in eine Standard-Skizzendatei, um Ressourcen mit aktualisierten Eigenschaften zu verarbeiten und zu exportieren (geklonte und aktualisierte Dateien sind normale Skizzendateien, die geöffnet, angezeigt, bearbeitet, gespeichert usw. werden können). )
Danach verwenden wir SketchTool (
unter Knoten eingeschlossen ), um alle Ressourcen automatisch in für Plattformen geeigneten Formaten zu exportieren. Für jede der mit der Marke verknüpften Dateien (oder vielmehr deren geklonten und aktualisierten Versionen) führen wir den folgenden Befehl aus:
sketchtool.run(`export slices ${cloneSketchFile} --formats=svg --scales=1 --output=${destinationFolder} --overwriting`);
Wie Sie vielleicht erraten haben, exportiert dieser Befehl Ressourcen in einem bestimmten Format in den Zielordner, optional mithilfe der Skalierung (wir behalten die ursprüngliche Skalierung vorerst bei). Der Schlüssel hier ist die Option
-overwriting
: Genau wie wir eine
assetsMetadata
Zusammenführung von
assetsMetadata
Objekten (entsprechend den „logischen“
assetsMetadata
) durchführen, führen wir beim Exportieren viele Dateien in einem Verzeichnis zusammen (bezogen auf die Marke / Plattform). Dies bedeutet, dass die Ressource - identifiziert durch den Namen des Layers - bereits in der vorherigen Skizzendatei vorhanden war und beim nächsten Export überschrieben wird. Auch dies ist nichts weiter als ein normaler Zusammenführungsvorgang.
In diesem Beispiel können sich einige Ressourcen jedoch als "Geister" herausstellen. Dies geschieht, wenn das Symbol in der Datei einem A / B-Test unterzogen wird, in der nachfolgenden Datei jedoch überschrieben wird. Anschließend werden die Variantendateien in den
assetsMetadata
exportiert, haben einen Link, der der Ressource im
assetsMetadata
Objekt entspricht (mit ihrem Schlüssel und ihren Eigenschaften), sind jedoch keiner
assetsMetadata
(aufgrund der tiefen Zusammenführung von
assetsMetadata
Objekten). Solche Dateien werden später gelöscht, bevor der Vorgang abgeschlossen wird.
Wie bereits erwähnt, erfordern unterschiedliche Plattformen unterschiedliche Ausgabeformate. iOS-Dateien passen zu PDFs, und wir können sie direkt mit dem Befehl SketchTool exportieren. JSX-Dateien sind für Mobile Web und VectorDrawable für Android erforderlich. Aus diesem Grund exportieren wir Ressourcen im SVG-Format in einen temporären Ordner und verarbeiten sie anschließend.
PDFs für iOS
Seltsamerweise ist PDF das einzige (?) Format, das Xcode und OS / iOS zum Importieren und Rendern von Vektorressourcen unterstützen (
hier eine kurze Erklärung der Wahl
von Apple).
Da wir über SketchTool direkt in PDF exportieren können, sind keine zusätzlichen Schritte erforderlich: Speichern Sie die Dateien einfach direkt im Zielordner, und fertig.
Reagieren / JSX-Webdateien
Im Web verwenden wir den SVGR-Bibliotheksknoten, mit dem Sie SVG in React-Komponenten konvertieren können. Wir möchten jedoch etwas abruptes tun: Das Symbol zur Laufzeit „dynamisch einfärben“ (Farben werden von Token übernommen). Zu diesem Zweck ändern wir vor dem Konvertieren die
fill
für Vektoren, auf die der allgemeine Stil zuvor auf Werte von Token angewendet wurde, die diesem Stil entsprechen.
Wenn also die aus Sketch exportierte Datei
badge-feature-like.svg folgendermaßen aussieht:
<?xml version="1.0" encoding="UTF-8"?> <svg width="128px" height="128px" viewBox="0 0 128 128" version="1.1" xmlns="<a href="http://www.w3.org/2000/svg">http://www.w3.org/2000/svg</a>" xmlns:xlink="<a href="http://www.w3.org/1999/xlink">http://www.w3.org/1999/xlink</a>"> <!-- Generator: sketchtool 52.2 (67145) -<a href="http://www.bohemiancoding.com/sketch"> http://www.bohemiancoding.com/sketch</a> --> <title>badge-feature-like</title> <desc>Created with sketchtool.</desc> <g id="Icons" fill="none" fill-rule="evenodd"> <g id="badge-feature-like"> <circle id="circle" fill="#E71032" cx="64" cy="64" r="64"> <path id="Shape" fill="#FFFFFF" d="M80.4061668,..."></path> </g> </g> </svg>
dann
sieht das endgültige
Symbol resource /
badge-feature-like.js folgendermaßen aus:
/* This file is generated automatically - DO NOT EDIT */ /* eslint-disable max-lines,max-len,camelcase */ const React = require('react'); module.exports = function badge_feature_like({ tokens }) { return ( <svg data-origin="pipeline" viewBox="0 0 128 128"> <g fill="none" fillRule="evenodd"> <circle fill={tokens.TOKEN_COLOR_FEATURE_LIKED_YOU} cx={64} cy={64} r={64} /> <path fill="#FFF" d="M80.4061668,..." /> </g> </svg> ); };
Wie Sie sehen können, haben wir die statische
fill
durch eine dynamische Farbe ersetzt, die Werte von Token übernimmt (sie können für die Komponente React
<Icon/>
über die Kontext-API verfügbar gemacht werden, dies ist jedoch eine andere Geschichte).
Diese Ersetzung ist dank der Sketch-Metadaten für die Assets des
assetsMetadata
Objekts möglich:
assetsMetadata
Sie die Ebenen rekursiv durchlaufen, können Sie einen DOM-Selektor (für das obige Beispiel
#Icons
#badge-feature-like #circle
)
#badge-feature-like #circle
und damit nach einem Knoten im SVG-Baum suchen und dessen Wert ersetzen
fill
(dafür benötigen wir die
Cheerio- Bibliothek).
VectorDrawable-Dateien für Android
Android unterstützt Vektorgrafiken im benutzerdefinierten
VectorDrawable- Vektorformat. Normalerweise erfolgt die Konvertierung von SVG nach VectorDrawable
direkt in Android Studio . Wir wollten den Prozess jedoch vollständig automatisieren und suchten nach einer Möglichkeit, mithilfe von Code zu konvertieren.
Nachdem wir verschiedene Tools und Bibliotheken studiert hatten, entschieden wir uns für
svg2vectordrawable . Es wird nicht nur aktiv unterstützt (auf jeden Fall aktiver als alle anderen), sondern auch funktionaler als die anderen.
Die Realität ist, dass VectorDrawable und SVG in ihrer Funktionalität nicht identisch sind: Einige SVG-Funktionen (z. B. radiale Verläufe und komplexe Hervorhebungen) werden von VectorDrawable nicht unterstützt, während andere erst seit kurzem unterstützt werden (beginnend mit Android API 24). Eines der daraus resultierenden Probleme besteht darin, dass ältere Versionen (bis zu 24)
den geraden und ungeraden Wert des Füllregelattributs nicht unterstützen . Wir bei Badoo benötigen jedoch Unterstützung für Android 5 und höher. Aus diesem Grund haben wir in einer der früheren Phasen die
fill
jedes Vektors in den Skizzendateien auf einen Wert
non-zero
.
Im Prinzip können Designer diese Aktion manuell ausführen:

Aber das ist leicht zu vergessen und einen Fehler zu machen. Aus diesem Grund haben wir beschlossen, dem Prozess für Android einen zusätzlichen Schritt hinzuzufügen, bei dem alle Vektoren in JSON automatisch in einen Wert
non-zero
konvertiert werden. Dies geschieht, damit Symbole beim Exportieren in SVG bereits im erforderlichen Format vorliegen und jedes erstellte VectorDrawable-Objekt von Geräten unter Android 5 unterstützt wird.
Die fertige Datei
badge-feature-like.xml sieht folgendermaßen aus:
<!-- This file is generated automatically - DO NOT EDIT --> <vector xmlns:android="<a href="http://schemas.android.com/apk/res/android">http://schemas.android.com/apk/res/android</a>" android:width="128dp" android:height="128dp" android:viewportWidth="128" android:viewportHeight="128"> <path android:fillColor="?color_feature_liked_you" android:pathData="M64 1a63 63 0 1 0 0 126A63 63 0 1 0 64 1z" /> <path android:fillColor="#FFFFFF" android:pathData="M80.406 ..." /> </vector>
In VectorDrawable-Dateien fügen wir Variablennamen für
fill
, die Design-Token über gängige Stile in Android-Anwendungen zugeordnet sind.

Es ist erwähnenswert, dass Android Studio strenge Anforderungen an die Organisation von Ressourcen stellt: Keine Unterordner und Großbuchstaben in den Namen! Wir mussten uns also ein neues Format für die
ic_icon-name__experiment-name__variant-name
:
ic_icon-name__experiment-name__variant-name
zu testenden Ressourcen sehen sie
ic_icon-name__experiment-name__variant-name
so aus:
ic_icon-name__experiment-name__variant-name
.
JSON-Wörterbuch als Ressourcenbibliothek
Nachdem die Ressourcendateien im endgültigen Format gespeichert wurden, müssen nur noch alle während der Assembly erhaltenen Metainformationen gesammelt und in einem „Wörterbuch“ gespeichert werden, das beim Importieren und Verwenden der Ressourcen durch die Codebasis verschiedener Plattformen verwendet werden soll.
Nachdem wir eine flache Liste von
assetsMetadata
aus dem
assetsMetadata
Objekt
assetsMetadata
gehen wir sie durch und überprüfen sie jeweils:
- Ist dies eine reguläre Ressource (z. B.
tabbar-livestream
) tabbar-livestream
wenn ja, dann lass es einfach;
- Wenn dies eine Option für einen A / B-Test ist (z. B. Experiment / Tabbar-Livestream [Variante] ), ordnen wir den Namen, den Pfad, die Namen des A / B-Tests und die Variante der Eigenschaft
abtests
die Basisressource (in unserem Fall Tabbar-Livestream ), wonach wir den Datensatz über die Variante aus der Liste / dem Objekt löschen (nur das Basiselement zählt);
- Wenn es sich um einen „Geist“ handelt, löschen Sie die Datei und entfernen Sie den Eintrag aus der Liste / dem Objekt.
Nach Abschluss dieses Vorgangs enthält das Wörterbuch eine Liste aller grundlegenden Symbole (und ihrer A / B-Tests, falls vorhanden) und nur dieser. Zu den Informationen zu den einzelnen Optionen gehören Name, Größe, Pfad und, falls das Symbol einem A / B-Test unterzogen wird, Informationen zu den verschiedenen Optionen.
Das Wörterbuch wird im JSON-Format im Zielordner für die
Marke und die
Plattform gespeichert. Hier ist beispielsweise die Datei
resources.json , die für die Blendr-Anwendung für Mobile Web generiert wurde:
{ "platform": "mw", "brand": "blendr", "assets": { "badge-feature-like": { "assetname": "badge-feature-like", "path": "assets/badge-feature-like.jsx", "width": 64, "height": 64, "source": "icons_common" }, "navigation-bar-edit": { "assetname": "navigation-bar-edit", "path": "assets/navigation-bar-edit.jsx", "width": 48, "height": 48, "source": "icons_common" }, "tabbar-livestream": { "assetname": "tabbar-livestream", "path": "assets/tabbar-livestream.jsx", "width": 128, "height": 128, "source": "icons_blendr", "abtest": { "this__is_an_experiment": { "control": "assets/this__is_an_experiment/tabbar-livestream__control.jsx", "variant1": "assets/this__is_an_experiment/tabbar-livestream__variant1.jsx", "variant2": "assets/this__is_an_experiment/tabbar-livestream__variant2.jsx" }, "a_second-experiment": { "control": "assets/a_second-experiment/tabbar-livestream__control.jsx", "variantA": "assets/a_second-experiment/tabbar-livestream__variantA.jsx" } } }, ... } }
Jetzt müssen nur noch alle
Assets- Ordner in ZIP-Archive gepackt werden, um das Herunterladen zu vereinfachen.
Zusammenfassung
Der im Artikel beschriebene Prozess, vom Klonen und Bearbeiten von Skizzendateien über das Exportieren und Konvertieren von Ressourcen in von Plattformen unterstützte Formate bis hin zum Speichern gesammelter Metainformationen in der Ressourcenbibliothek, wird mit jeder im Build-Skript angekündigten Marke wiederholt.
Hier ist ein Screenshot, der das Erscheinungsbild der Ordner
src und
dist nach Abschluss des Vorgangs zeigt:

In dieser Phase können Sie mit einem einfachen Befehl alle Ressourcen (JSON-, ZIP- und Ressourcendateien) auf den Remotespeicher hochladen und für alle Plattformen zum Herunterladen und Verwenden in der Codebasis verfügbar machen.
Wie genau Plattformen Ressourcen empfangen und verarbeiten (unter Verwendung von speziell für diesen Zweck erstellten benutzerdefinierten Skripten), geht nicht über den Rahmen dieses Artikels hinaus. Und diese Frage wird wahrscheinlich in einem der folgenden Beiträge eines meiner Kollegen behandelt.
Schlussfolgerung (und gewonnene Erkenntnisse)
Ich habe Sketch immer geliebt. Seit vielen Jahren ist das Programm das Standardwerkzeug für Entwickler und Designer. Daher war ich sehr neugierig auf Integrationstools wie
HTML-Sketchapp und andere ähnliche Tools, die wir im Workflow und in unseren Pipelines verwenden können.
Ich habe mich
wie viele andere immer um einen solchen (idealen) Prozess
bemüht :

Ich muss jedoch zugeben, dass ich anfing zu bezweifeln, dass Sketch ein geeignetes Werkzeug ist, insbesondere angesichts des Designsystems. Aus diesem Grund habe ich mich mit anderen Diensten befasst, z. B. Figma mit seinen offenen APIs und Framer X mit praktischer Integration in React, da ich keine Ahnung hatte, wie sich Sketch in Richtung Integration mit dem Code bewegt (was auch immer es war).
Dieses Projekt hat mich also überzeugt. Nicht vollständig, aber in vielerlei Hinsicht.
Obwohl Sketch seine APIs nicht öffnet, dient das Gerät der internen Struktur seiner Dateien als eine Art "inoffizielle" API. Ersteller können verschlüsselte Namen verwenden oder Schlüssel in JSON-Objekten ausblenden. Stattdessen halten sie sich an eine klare, lesbare und konzeptionelle Namenskonvention. Ich denke nicht, dass dies ein Unfall ist.
Die Tatsache, dass Skizzendateien auf diese Weise verwaltet werden können, hat mir den Weg für viele zukünftige Entwicklungen und Verbesserungen geöffnet: von Plugins zur Überprüfung des Namens, des Stils und der Struktur von Ebenen für Symbole bis zur Integration in unser Wiki und zur Dokumentation unseres Design-Systems (gegenseitig). Durch das Erstellen von Knotenanwendungen auf
Electron oder
Carlo können wir Designern das Ausführen vieler Routineaufgaben erleichtern.
( , ) , Sketch- Cosmos « » — - Cosmos. , ( ; , — ). , — , , .
, Sketch- , , MVP-, . , , . , , -, — , . , .
:
,
. ,
.
, , — . , , , (, A/B-), Node.js Sketch.
! .
(Mobile Web), ,
(Android)
(iOS), .
Danke Jungs! .