
TL; DR
Usando un script de compilación personalizado en Node JS, es posible manipular una serie de archivos de Sketch y luego, usando una herramienta de Sketch interna, exportar automáticamente sus activos, para generar múltiples bibliotecas de iconos, para múltiples plataformas y diferentes marcas, que admiten dinámicas coloración de los activos a través de tokens de diseño, y también pruebas AB de los activos a través de la convención de nomenclatura. Fácil guisante :)
Bueno, en realidad no es tan fácil, pero ciertamente se puede hacer. Esta publicación es una explicación detallada de cómo lo hicimos y de lo que descubrimos en el camino.
El problema que intentamos resolver
En
Badoo creamos una aplicación de citas. En realidad, múltiples aplicaciones de citas. Para múltiples plataformas (
iOS ,
Android ,
Web móvil ,
Web de escritorio ), en
varios equipos .
Usamos cientos de iconos en nuestras aplicaciones. Algunos de ellos son iguales en diferentes aplicaciones, algunos son muy específicos de las marcas que reflejan las aplicaciones. Los iconos evolucionan continuamente, en sincronía con la evolución del diseño. A veces se agregan íconos completamente nuevos, mientras que otros se actualizan y otros se descartan (aunque a menudo permanecen en la base de código).
Nuestro equipo de diseño diseña y mantiene los íconos, y hasta ahora la única forma de proporcionar los activos correctos a los diferentes equipos, plataformas y aplicaciones, era enviándolos por correo electrónico, chat o dropbox. Esto no solo lleva mucho tiempo, sino que casi siempre es propenso a errores. De hecho, encontramos errores cada vez (¡somos humanos!): Los iconos se actualizarían en una plataforma pero no en otra; o faltarían iconos o estarían en el formato o tamaño incorrecto. Entonces, hubo una constante ida y vuelta entre diseñadores y desarrolladores; los desarrolladores exportarían íconos directamente desde el archivo de Sketch, y los íconos se agregarían a la base de código pero sin verificar si ya existían íconos similares (y si estaban disponibles para su reutilización). Estoy seguro de que sabes de lo que estoy hablando.
En Badoo tenemos un
sistema de diseño, llamado Cosmos , y recientemente presentamos una
biblioteca de tokens de diseño en múltiples plataformas (Mobile Web, Android e iOS) tanto para nuestra aplicación principal como para sus etiquetas blancas. Esencialmente, ahora podemos comunicar decisiones de diseño (como el borde de un botón, el color de fondo de una página de características en particular, el tamaño de fuente del Título 1 o la duración de una animación para una ventana emergente) utilizando valores de diseño elementales, todo procesado y entregado automáticamente a todas las aplicaciones, y todas las plataformas que consumen estos tokens de diseño en sus aplicaciones.
La forma en que ahora podemos transformar una idea de diseño, como por ejemplo un cambio de color, en código real en producción, con solo unos pocos clics y casi en ningún momento, realmente ha impresionado a los gerentes de producto y diseñadores por igual.
Entonces, su siguiente pregunta (y solicitud) fue: ¿puedes hacer algo similar para los activos? Y nuestra respuesta fue: sí, ¡nosotros (probablemente) podemos!
Fue un gran salto de fe en ese momento, debo admitirlo. Teníamos algunas ideas sobre cómo hacerlo, pero no estábamos del todo seguros de si era técnicamente factible, con todas las restricciones bajo las cuales operamos. Acordamos comenzar con un proyecto MVP, pero al final todo había ido tan bien que se convirtió en nuestro producto final, con todas las características necesarias.
Los requisitos
Los requisitos para el MVP eran muy claros: crear una tubería que pudiera tomar un archivo de boceto y exportar todos los íconos incluidos en el archivo, en diferentes formatos, para diferentes plataformas, con cada ícono adecuado para su uso en pruebas AB.
Esto es complicado porque, en nuestros productos, un ícono puede tener muchos colores y / o formas diferentes para diferentes marcas / etiquetas blancas (aunque la base de código de la aplicación es la misma, así como el nombre del ícono).
Mire algunos de los íconos utilizados en nuestras aplicaciones y notará que algunos son idénticos, algunos son muy similares entre sí, pero para algunos detalles, mientras que otros son bastante diferentes, tanto en sus formas como en sus colores:
Una comparación del ícono para las diferentes marcasAhora, los colores utilizados en los iconos no son solo colores simples, sino que coinciden con los colores exactos indicados en los
tokens de diseño para esa marca y sus características específicas:
Comparación de los colores en diferentes marcas. Los valores de color se especifican como tokens de diseño.Por lo tanto, nuestro objetivo con esta nueva cartera de activos no era solo automatizar el proceso de generación y entrega de los iconos, para todas las diferentes plataformas y marcas, sino más bien poder colorear los iconos "dinámicamente" de acuerdo con la marca / blanco -etiqueta.
Sketch y sketchtool
Sketch es la principal herramienta de diseño que utiliza nuestro equipo de diseño. Aunque consideramos otras opciones (
Figma , principalmente), sabíamos que Sketch era el formato de los archivos fuente que íbamos a utilizar para este proyecto (simplemente porque es la herramienta en la que nuestros diseñadores son más competentes, y es el formato de los archivos donde se usan los íconos / activos existentes, entre otras razones).
El hecho es que, al comienzo del proyecto, ni siquiera estábamos seguros de qué formatos finales esperaban las plataformas. En nuestra opinión, el proceso iba a ser bastante básico como este: exportar los íconos en formato SVG desde el archivo Sketch y luego consumir los archivos SVG en Mobile Web y Android, y para iOS encontrar una biblioteca que pueda convertir SVG a PDF. Y ya está. Ese era el plan cuando comenzamos, aunque no teníamos idea de si funcionaría o de las incógnitas desconocidas que podríamos encontrar (por lo tanto, el MVP para ver si era factible y, de ser así, cuánto esfuerzo podría implicar )
No sé si alguna vez ha trabajado con "convertidores de PDF", pero en mi experiencia, generalmente son un dolor. Ellos "casi" hacen el trabajo, pero nunca al 100% que realmente necesita. Entonces, en el fondo de mi mente, sentí que estábamos caminando por un camino peligroso.
Sketch tiene una forma de exportar activos que es bastante perfecta, nunca he tenido un problema con ella (ya sea SVG, PDF u otros formatos). Así que quería ver si había otras formas de interactuar con Sketch, usar su motor para exportar activos directamente a través de Sketch, posiblemente de manera programática (también me preguntaba si se podría construir un complemento personalizado, aunque eso hubiera significado mucho trabajo para mí, ¡no solo porque no tengo experiencia en ese campo!).
Sabía que, internamente, Sketch no es más que un archivo zip (si cambia el nombre de un archivo
.sketch a
.zip , haga doble clic para descomprimirlo y abra la carpeta resultante, verá una lista de archivos JSON y un mapa de bits utilizado como vista previa):
Estructura interna de un archivo de boceto, una vez descomprimidoEntonces, comencé a explorar los diferentes archivos JSON, tratando de entender las conexiones y dependencias entre ellos.
Me di cuenta de que de alguna manera, a pesar de que los archivos JSON están profundamente anidados (¡y bastante grandes!), Las relaciones entre las diferentes entidades dentro de sus objetos no son demasiado complicadas: tienes páginas, mesas de trabajo y capas; dentro de las capas tienes las rutas y puedes compartir estilos entre ellas; cada una de estas entidades tiene una ID única que se usa para mantener una referencia entre los diferentes archivos; y todos los objetos de "página" se guardan en archivos JSON, almacenados en una subcarpeta llamada
páginas , con la ID de la página utilizada como nombre del archivo.
Un descubrimiento significativo que hice, durante esta exploración, fue que
los nombres de las capas, páginas y estilos son solo etiquetas, y se pueden cambiar en cualquier momento, sin comprometer el funcionamiento interno del archivo Sketch. Lo que importa es la identificación única asignada a ellos, y esto nunca se expone al usuario final (aunque, puede leerse y referenciarse dentro de los archivos JSON). Aquí hay un ejemplo de cómo se ve la ID única de un estilo:
{ "_class": "sharedStyle", "do_objectID": "49BA4E98-8D63-435C-81D9-E2F6CDB63136", "name": "name-of/the-style", "value": { "_class": "style", "endMarkerType": 0, "fills": [ { "_class": "fill", "isEnabled": true, "color": { "_class": "color", "alpha": 1, "blue": 0.7176470588235294, "green": 0.4627450980392159, "red": 0 }, "fillType": 0, "noiseIndex": 0, "noiseIntensity": 0, "patternFillType": 1, "patternTileScale": 1 } ], "miterLimit": 10, "startMarkerType": 0, "windingRule": 1 } }
Esto me dio una idea: que tal vez podríamos usar convenciones específicas en los nombres de las mesas de trabajo y de las páginas, para declarar algún tipo de metainformación sobre las relaciones entre los diferentes activos, y usarlos mediante programación en el momento de la construcción.
Sketchtool
En este punto, al final de las exploraciones iniciales, el plan había cambiado de
"exportemos los íconos en SVG y luego los convertimos" a
"construyamos un complemento que, dentro de Sketch, nos permite exportar directamente los íconos en su versión final formato " . Pero incluso entonces, el plan todavía estaba muy borroso (y la viabilidad técnica aún era incierta).
Mientras miraba los complementos existentes, especialmente en su código fuente, para ver si podían interactuar con las API de exportación de Sketch y cómo podrían interactuar con ellos, me encontré con una herramienta de la que nunca había oído hablar antes: Sketchtool.
Sketchtool es una herramienta oficial de Sketch (oficial como en: desarrollada por Bohemian Coding), que
según la documentación :
... es una utilidad de línea de comandos que se incluye con Sketch, que le permite realizar algunas operaciones con documentos de Sketch, como inspeccionarlos o exportar activos. También le permite controlar Sketch desde la línea de comandos para realizar algunas acciones (como ejecutar complementos, por ejemplo).
¿Espera ... una
utilidad de línea de comandos para realizar operaciones como la
exportación de activos ? Justo lo que estaba buscando! Además, al ser una herramienta oficial, no habría problemas de versiones, obsolescencia, mantenimiento, etc.
Comencé a investigarlo de inmediato y leí la documentación, que se estableció en
una sola página en el sitio web de Sketch (casi no he encontrado otros recursos o páginas al respecto, por lo que es comprensible que nunca haya oído hablar de él). it)
Sketchtool se incluye directamente con Sketch, y puede encontrarlo dentro de Sketch en esta ruta:
Sketch.app/Contents/Resources/sketchtool/
Cuando lo inicie en su CLI con el comando:
$ /Applications/Sketch.app/Contents/Resources/sketchtool/bin/sketchtool
esta es la salida que ves en tu terminal (lo he simplificado un poco):
Usage: sketchtool <command> [<args>] [--formats=<string>] [--use-id-for-name{=YES|NO}] [--export-page-as-fallback{=YES|NO}] [--serial{=YES|NO}] [--context=<string>] [--application=<path>] [--without-activating{=YES|NO}] [--item=<string>] [--items=<string>] [--safemode{=YES|NO} | --no-safemode | -S {<YES|NO>}] [--max-size=<float> | -m <float>] [--background=<string> | -g <string>] [--compression=<float> | -c <float>] [--new-instance{=YES|NO}] [--reveal{=YES|NO}] [--timeout=<float>] [--include-symbols{=YES|NO}] [--bounds=<rectangle>] [--outputJSON=<path>] [--filename=<string>] [--wait-for-exit{=YES|NO}] [--scales=<path>] [--overwriting{=YES|NO}] [--group-contents-only{=YES|NO}] [--trimmed{=YES|NO}] [--help] [--progressive{=YES|NO}] [--save-for-web{=YES|NO}] [--output=<path>] Commands: dump Dump out the structure of a document as JSON. export artboards Export one or more artboards export layers Export one or more layers export pages Export an area from one or more pages export preview Export a preview image for a document export slices Export one or more slices help Show this help message. list artboards List information on the document's artboards. list formats List the supported export formats. list layers List information on all of the document's layers. list pages List information on the document's pages. list slices List information on the document's slices. metadata List the metadata for a document. run Run a command from a plugin, inside Sketch. show Show the location of the various sketch folders. See 'sketchtool help <command>' for more information on a specific command.
Como puede ver, la herramienta tiene cuatro funciones principales:
leer / volcar los metadatos de los archivos JSON internos; para
enumerar las entidades dentro de un archivo; para
exportar estas entidades; y para
ejecutar un comando expuesto por un complemento. Además, cada comando tiene muchas
opciones disponibles. En el caso del comando de exportación, casi todas las opciones que encuentra en el
panel de exportación también están disponibles a través de la línea de comando de Sketchtool:
Panel "Exportar" en Sketch, con las opciones disponiblesEsto significa que Sketch se puede usar directamente como "motor" de exportación a través de
sketchtool , sin la necesidad de convertidores externos (por ejemplo, de SVG a PNG o PDF). Gran cosa!
Una prueba rápida usando
sketchtool y un simple archivo de Sketch con algunos íconos dentro, confirmó todas las suposiciones iniciales: solo usando esta herramienta simple, podemos evitar usar exportadores de terceros y crear nuestros propios exportadores personalizados: ¡Sketch lo hace todo!
Los archivos de croquis
Una vez que supimos que Sketch era la herramienta que íbamos a usar, tanto para almacenar como para exportar los iconos, llegó el momento de recopilar los iconos utilizados en nuestras aplicaciones en un archivo de Sketch.
Inicialmente, solo planeábamos trabajar con un conjunto limitado de íconos, aquellos para el proyecto MVP, pero rápidamente nos dimos cuenta de que hubiera sido mejor recopilarlos todos de una vez, para poder detectar duplicados, inconsistencias, omisiones de inmediato, etc.
Nuestros diseñadores hicieron un trabajo increíble y en solo un par de días una gran parte de los activos utilizados en sus archivos de Sketch se han recopilado y organizado en un solo archivo. En este punto, el archivo de Sketch se veía así:
Descripción general del archivo Sketch que contiene los iconos utilizados en nuestra aplicación.En el archivo, cada ícono tiene su propia mesa de trabajo, nombrada con el nombre deseado del ícono (que luego Sketch utilizará como nombre de archivo al exportar los activos).
Todos los trazados se convierten en contornos, y los trazados combinados (generalmente como
unión o
sustracción ) se aplanan en una sola forma. Esto garantiza que los activos generados mantengan la apariencia visual perfecta que tienen en el archivo fuente y una compatibilidad óptima con las diversas plataformas.
Ejemplo de cómo se organizan los iconos (y sus capas) en el archivo de boceto de activos. El fondo rosa claro aplicado a las mesas de trabajo crea un contraste visual con las áreas blancas.Colorear dinámicamente los iconos con estilos compartidos (y tokens de diseño)
Una vez que reunimos los íconos, el siguiente paso fue aplicarles los colores correctos. Lo que hicimos fue crear un conjunto de
estilos compartidos predefinidos
en Sketch , con nombres que coincidían con los de los
tokens de diseño utilizados en nuestro
sistema de diseño, y luego usarlos para aplicar colores a los iconos.
Así es como se aplica un estilo a una capa:
Capa en Sketch con un estilo predefinido (color de relleno).Y así es como se declaran los estilos y luego se aplican a un elemento:
Cómo hemos decidido organizar los estilos en SketchLa convención de nombres es muy importante aquí. Los diseñadores pueden organizar los estilos en cualquier subcarpeta, siempre que el nombre del estilo coincida con el nombre del token de diseño correspondiente para ese color. Esto es, por lo que el script de compilación puede hacer referencia programáticamente más adelante.
Páginas y nombres de mesa de trabajo utilizados para pruebas AB
En este punto, era hora de comprender cómo garantizar que los diseñadores pudieran realizar pruebas AB en los iconos. Una vez más, al final decidimos confiar en las convenciones de nomenclatura (gran fan de KISS aquí).
En este caso, utilizamos los
nombres de las
páginas para detectar cuándo un conjunto de iconos era una prueba / experimento AB (usando "
XP_" como prefijo) y los
nombres de la
mesa de trabajo para detectar a qué activo se refería la prueba AB y sus diferentes variantes ( encerrado entre corchetes).
Cómo se usa la convención de nomenclatura en páginas y mesas de trabajo para "declarar" una prueba AB. Aviso: los íconos son solo ejemplos creados especialmente para fines de prueba, no son íconos reales utilizados en un producto :)
Los nombres utilizados para las pruebas y las opciones no son nombres genéricos: deben coincidir con los
ID de nombres
únicos asignados a los experimentos / opciones en nuestra herramienta interna de división de usuarios. De esta manera, los activos se pueden asociar más tarde correctamente con el grupo de usuarios de prueba AB correcto.
Múltiples archivos para múltiples marcas.
La última pieza del rompecabezas fue: ¿cómo admitimos diferentes formas del mismo ícono para diferentes marcas?

Este era
un requisito muy importante para los gerentes de producto , y teníamos varias opciones disponibles para usar. Al principio, pensamos en usar diferentes páginas en el mismo archivo de Sketch, con diferentes nombres de página para cada marca; pero pronto nos dimos cuenta de que haría mucho más complejo y más difícil para los diseñadores mantener los iconos sincronizados entre las diferentes marcas. Así que concluimos que la solución era tener múltiples archivos: un
archivo "común" , donde almacenamos todos los íconos que eran idénticos para las diferentes marcas, y
archivos específicos de la marca para íconos que
anulaban los íconos "base" en el común archivo.

En este punto, los archivos de Sketch estaban listos. Estábamos listos para comenzar a escribir código.
Continuará