Gerando ícones de várias plataformas e com várias marcas com o Sketch e um script Node.js. - Parte # 1



TL; DR


Usando um script de construção customizado no Nó JS, é possível manipular uma série de arquivos do Sketch e, em seguida, usando uma ferramenta interna do Sketch, exportar automaticamente seus ativos, gerar várias bibliotecas de ícones, para várias plataformas e marcas diferentes, que suportam dinâmica colorização dos ativos por meio de tokens de design e também teste AB dos ativos por convenção de nomenclatura. Fácil peasy :)


Bem, na verdade não é tão fácil, mas certamente pode ser feito. Este post é uma explicação detalhada de como o fizemos e o que descobrimos ao longo do caminho.

O problema que estávamos tentando resolver


No Badoo, criamos um aplicativo de namoro. Na verdade, vários aplicativos de namoro. Para várias plataformas ( iOS , Android , Web móvel , Web para desktop ), em várias equipes .

Usamos centenas de ícones em nossos aplicativos. Alguns deles são iguais em aplicativos diferentes, outros são muito específicos para as marcas que os aplicativos refletem. Os ícones estão em constante evolução, em sincronia com a evolução do design. Às vezes, são adicionados ícones completamente novos, enquanto outros são atualizados e outros ainda são descartados (embora, geralmente, permaneçam na base de código).

Nossa equipe de design projeta e mantém os ícones, e até agora a única maneira de fornecer os ativos corretos para as diferentes equipes, plataformas e aplicativos, era enviá-los por email, chat ou dropbox. Isso não apenas consome tempo, mas é quase sempre propenso a erros. De fato, descobrimos que sempre ocorriam erros (somos humanos!): Os ícones seriam atualizados em uma plataforma, mas não em outra; ou os ícones estariam ausentes ou no formato ou tamanho errado. Portanto, havia uma constante alternância entre designers e desenvolvedores; os desenvolvedores exportariam ícones diretamente do arquivo Sketch e os ícones seriam adicionados à base de código, mas sem verificação para ver se ícones semelhantes já existiam (e estavam disponíveis para reutilização). Tenho certeza que você sabe do que estou falando.

No Badoo, temos um Sistema de Design, chamado Cosmos , e recentemente introduzimos uma biblioteca de Design Tokens em várias plataformas (Web móvel, Android e iOS), tanto para o nosso aplicativo principal quanto para seus rótulos em branco. Agora, basicamente, podemos comunicar decisões de design (como a borda de um botão, a cor de plano de fundo de uma página de recurso específica, o tamanho da fonte do Título 1 ou a duração de uma animação para um pop-up) usando valores elementares de design, tudo processado e entregue automaticamente a todos os aplicativos e a todas as plataformas que consomem esses tokens de design em seus aplicativos.

Agora, como somos capazes de transformar uma ideia de design, como, por exemplo, uma mudança de cor, em código real na produção, em apenas alguns cliques e quase em qualquer momento, realmente impressionou os gerentes e designers de produtos.

Então, a próxima pergunta (e solicitação) foi: você pode fazer algo semelhante pelos ativos? E nossa resposta foi: sim, nós (provavelmente) podemos!

Foi um grande salto de fé na época, tenho que admitir. Tínhamos algumas idéias de como fazê-lo, mas não tínhamos certeza se era tecnicamente viável, com todas as restrições em que operamos. Concordamos em começar com um projeto MVP, mas no final tudo correu tão bem que se tornou nosso produto final, com todos os recursos necessários.

Os requisitos


Os requisitos para o MVP eram muito claros: crie um pipeline que possa pegar um arquivo Sketch e exportar todos os ícones incluídos no arquivo, em diferentes formatos, para plataformas diferentes, com cada ícone adequado para uso no teste AB.

Isso é complicado porque, em nossos produtos, um ícone pode ter muitas cores e / ou formas diferentes para diferentes marcas / etiquetas em branco (embora a base de código do aplicativo seja o mesmo e o nome do ícone).

Observe alguns dos ícones usados ​​em nossos aplicativos e você notará que alguns são idênticos, alguns são muito parecidos entre si, mas com alguns detalhes, enquanto outros são bem diferentes, tanto em suas formas quanto em cores:


Uma comparação do ícone para as diferentes marcas

Agora, as cores usadas nos ícones não são apenas cores simples, mas correspondem às cores exatas indicadas nos tokens de design para essa marca e seus recursos específicos:


Comparação das cores entre diferentes marcas. Os valores das cores são especificados como tokens de design.

Portanto, nosso objetivo com esse novo pipeline de ativos não era apenas automatizar o processo de geração e entrega dos ícones, para todas as diferentes plataformas e marcas, mas também poder "dinamicamente" colorir os ícones de acordo com a marca / branco -label.

Sketch e sketchtool


O Sketch é a principal ferramenta de design que nossa equipe de design usa. Embora tenhamos considerado outras opções ( Figma , principalmente), sabíamos que o Sketch era o formato dos arquivos de origem que usaríamos para este projeto (simplesmente porque é a ferramenta na qual nossos designers são mais proficientes e é o formato dos arquivos em que os ícones / ativos existentes são usados, entre outros motivos).

O fato é que, no início do projeto, não tínhamos certeza do formato final esperado pelas plataformas. Em nossa opinião, o processo seria bem básico assim: exporte os ícones no formato SVG do arquivo Sketch e consuma os arquivos SVG no Mobile Web e Android, e para iOS encontre uma biblioteca que possa converter SVGs em PDFs. E é isso. Esse era o plano quando começamos, embora não tivéssemos ideia se funcionaria, ou sobre as incógnitas desconhecidas que poderíamos encontrar (portanto, o MVP para ver se era viável e, se sim, quanto esforço isso poderia acarretar. )

Não sei se você já trabalhou com "conversores de PDF", mas, na minha experiência, eles geralmente são uma dor. Eles "quase" fazem o trabalho, mas nunca para os 100% que você realmente precisa. Então, no fundo da minha mente, senti que estávamos trilhando um caminho perigoso.

O Sketch tem uma maneira de exportar ativos que são praticamente perfeitos, nunca tive problemas com ele (seja SVG, PDF ou outros formatos). Então, eu queria ver se havia outras maneiras de interagir com o Sketch, usar seu mecanismo para exportar ativos diretamente via Sketch, possivelmente de maneira programática (eu também queria saber se um plug-in personalizado poderia ser construído, embora isso significasse muito trabalho para mim, não apenas porque não tenho experiência nesse campo!).

Eu sabia que internamente o Sketch não passa de um arquivo zip (se você renomear um arquivo .sketch para .zip , clique duas vezes para descompactá-lo e abrir a pasta resultante, verá uma lista de arquivos JSON e um bitmap usado como pré-visualização):


Estrutura interna de um arquivo de esboço, uma vez descompactado

Então, comecei a explorar os diferentes arquivos JSON, tentando entender as conexões e dependências entre eles.

Percebi que, de alguma forma, apesar dos arquivos JSON serem profundamente aninhados (e bastante grandes!), As relações entre as diferentes entidades dentro de seus objetos não são muito complicadas: você tem páginas, pranchetas e camadas; dentro das camadas, você tem os caminhos e pode ter estilos compartilhados entre elas; cada uma dessas entidades possui um ID exclusivo usado para manter uma referência entre os diferentes arquivos; e todos os objetos "page" são salvos em arquivos JSON, armazenados em uma subpasta chamada pages , com o ID da página usado como nome do arquivo.

Uma descoberta importante que fiz, durante esta exploração, foi que os nomes das camadas, páginas e estilos são apenas rótulos e podem ser alterados a qualquer momento, sem comprometer o funcionamento interno do arquivo Sketch. O que importa é o ID exclusivo atribuído a eles, e isso nunca é exposto ao usuário final (embora possa ser lido e referenciado nos arquivos JSON). Aqui está um exemplo de como o ID exclusivo de um estilo se parece:

{ "_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 } } 

Isso me deu uma idéia: que talvez pudéssemos usar convenções específicas nos nomes das pranchetas e das páginas, para declarar algum tipo de meta-informação sobre as relações entre os diferentes ativos e usá-las de forma programática no tempo de construção.

Sketchtool


Nesse ponto, no final das explorações iniciais, o plano havia mudado de "vamos exportar os ícones no SVG e depois convertê-los" para "vamos criar um plug-in que, no Sketch, nos permita exportar diretamente os ícones em sua versão final. formato " . Mas, mesmo assim, o plano ainda estava muito confuso (e a viabilidade técnica ainda era incerta).

Foi enquanto eu olhava os plug-ins existentes, especialmente o código-fonte, para ver se e como eles poderiam interagir com as APIs de exportação do Sketch. Encontrei uma ferramenta da qual nunca tinha ouvido falar antes: o Sketchtool.

O Sketchtool é uma ferramenta oficial do Sketch (oficial como em: desenvolvida pela Bohemian Coding), que de acordo com a documentação :
... é um utilitário de linha de comando que acompanha o Sketch, que permite executar algumas operações com documentos do Sketch, como inspecioná-los ou exportar ativos. Também permite controlar o Sketch na linha de comando para executar algumas ações (como executar plug-ins, por exemplo).

Espere ... um utilitário de linha de comando para executar operações como exportar ativos ? Apenas o que eu estava procurando! Além disso, sendo uma ferramenta oficial, não haveria problemas de versões, obsolescência, manutenção etc.

Comecei a examiná-lo imediatamente e a ler a documentação, que gradualmente se tornou apenas uma página no site do Sketch (não encontrei quase nenhum outro recurso ou página por aí, então é compreensível que eu nunca tenha ouvido falar sobre isso)

O Sketchtool é fornecido diretamente com o Sketch e você pode encontrá-lo no Sketch neste caminho: Sketch.app/Contents/Resources/sketchtool/

Quando você o inicia em sua CLI com o comando:
$ /Applications/Sketch.app/Contents/Resources/sketchtool/bin/sketchtool

esta é a saída que você vê no seu terminal (eu simplifiquei um pouco):

 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 você pode ver, a ferramenta possui quatro funções principais: ler / despejar os metadados dos arquivos JSON internos; listar as entidades dentro de um arquivo; exportar essas entidades; e para executar um comando exposto por um plugin. Além disso, cada comando tem muitas opções disponíveis. No caso do comando export, quase todas as opções encontradas no painel de exportação também estão disponíveis na linha de comando do Sketchtool:


Painel "Exportar" no Sketch, com as opções disponíveis

Isso significa que o Sketch pode ser usado diretamente como "mecanismo" de exportação via ferramenta de desenho , sem a necessidade de conversores externos (de SVG para PNG ou PDF, por exemplo). Grande coisa!

Um teste rápido usando o sketchtool e um arquivo simples do Sketch com alguns ícones no interior confirmou todas as suposições iniciais: ao usar esta ferramenta simples, podemos evitar o uso de exportadores de terceiros e a criação de nossos próprios exportadores personalizados: o Sketch faz tudo!

Os arquivos de rascunho


Depois que soubemos que o Sketch era a ferramenta que íamos usar, para armazenar e exportar os ícones, era hora de realmente coletar os ícones usados ​​em nossos aplicativos em um arquivo do Sketch.

Inicialmente, planejávamos trabalhar apenas com um conjunto limitado de ícones, para o projeto MVP, mas rapidamente percebemos que seria melhor coletá-los todos de uma vez, para poder detectar imediatamente duplicatas, inconsistências, omissões, etc.

Nossos designers fizeram um trabalho incrível e, em apenas alguns dias, grande parte dos ativos usados ​​nos arquivos do Sketch foi coletada e organizada em um único arquivo. Nesse ponto, o arquivo de esboço estava assim:


Visão geral do arquivo Sketch contendo os ícones usados ​​em nosso aplicativo.

No arquivo, cada ícone tem sua própria prancheta, nomeada com o nome desejado do ícone (posteriormente usado pelo Sketch como nome do arquivo ao exportar os ativos).

Todos os caminhos são convertidos em contornos e os caminhos combinados (geralmente como união ou subtração ) são nivelados em uma única forma. Isso garante que os ativos gerados mantenham a aparência visual perfeita no arquivo de origem e a compatibilidade ideal com as várias plataformas.



Exemplo de como os ícones (e suas camadas) são organizados no arquivo de esboço de ativos. O fundo rosa claro aplicado às pranchetas cria um contraste visual com as áreas brancas.

Colorir dinamicamente os ícones com Estilos Compartilhados (e Tokens de Design)


Depois de coletarmos os ícones, o próximo passo era aplicar as cores certas a eles. O que fizemos foi criar um conjunto de Estilos compartilhados predefinidos no Sketch , com nomes que correspondessem aos dos tokens de design usados ​​em nosso sistema de design e usá-los para aplicar cores aos ícones.

É assim que um estilo é aplicado a uma camada:


Camada no Sketch com um estilo predefinido (cor de preenchimento).

E é assim que os estilos são declarados e aplicados a um elemento:


Como decidimos organizar os estilos no Sketch

A convenção de nomenclatura é muito importante aqui. Os designers podem organizar os estilos em qualquer subpasta, desde que o nome do estilo corresponda ao nome do token de design correspondente para essa cor. Isso é, para que possa ser referenciado programaticamente pelo script de construção posteriormente.

Páginas e nomes de prancheta usados ​​para testes AB



Nesse momento, estava na hora de entender como garantir que os designers pudessem realizar testes AB nos ícones. Mais uma vez, no final, decidimos confiar nas convenções de nomenclatura (grande fã do KISS aqui).

Nesse caso, usamos os nomes das páginas para detectar quando um conjunto de ícones era um teste / experimento AB (usando " XP_" como prefixo) e os nomes da prancheta para detectar a qual ativo o teste AB estava se referindo e suas diferentes variantes ( entre colchetes).


Como a convenção de nomenclatura em páginas e pranchetas é usada para "declarar" um teste AB. Aviso: os ícones são apenas exemplos criados especialmente para fins de teste, não são ícones reais usados ​​em um produto :)

Os nomes usados ​​para os testes e as opções não são nomes genéricos: eles devem corresponder aos IDs de nome exclusivo atribuídos às experiências / opções em nossa ferramenta interna de divisão de usuários. Dessa forma, os ativos podem ser associados mais tarde corretamente ao grupo de usuários de teste AB correto.

Vários arquivos para várias marcas


A última peça do quebra-cabeça foi: como apoiamos diferentes formas do mesmo ícone, para diferentes marcas?



Esse era um requisito muito importante para os gerentes de produto e tínhamos várias opções disponíveis para uso. Inicialmente, pensamos em usar páginas diferentes no mesmo arquivo de esboço, com nomes de páginas diferentes para cada marca; mas logo percebemos que tornaria muito mais complexo e mais difícil para os designers manter os ícones sincronizados entre as diferentes marcas. Concluímos que a solução era ter vários arquivos: um arquivo "comum" , onde armazenávamos todos os ícones idênticos para as diferentes marcas e arquivos específicos da marca para ícones que estavam substituindo os ícones "básicos" no comum arquivo



Nesse ponto, os arquivos do Sketch estavam prontos. Estávamos prontos para começar a escrever código.

Para ser continuado.

Source: https://habr.com/ru/post/pt441040/


All Articles