Blog >

Escalando A Entrega De Ui Com O Storybook

 
Featured Image
 

Felipe Norato, Desenvolvedor na Sinch, dividiu conosco nesse texto um pouco mais sobre a sua experiência com o storybook. Confira!

Cada vez mais temos aplicações web mais complexas com vários fluxos e com o layout mais apurado. As telas vêm sendo projetadas para servir ao usuário uma explosão de cores, interações, animações, texturas, sensações, ufa! Vocês devem imaginar o trabalho que dá para fazer e dar manutenção isso tudo, ainda mais com equipes que estão crescendo e ficando multiespecializada, possuindo várias roles como Frontend, Backend, Devops, Designers, entre outras roles.

Uma coisa é fato, manter todo esse código é complicado, mesmo quando temos testes unitários, mas, e o visual? Como fazemos o desenvolvimento da parte visual da aplicação escalar?

Não importa a arquitetura usada, temos que criar um Hall de Componentes Genéricos! Estes darão a cara da aplicação servindo de peças de Lego para construir cada tela e nos fará economizar de forma exponencial o tempo de desenvolvimento, e, assim reduzindo o tempo de entrega. Definição de felicidade!

O processo de Desenvolvimento

Se imagine um lugar onde nada existe, somente uma tela em branco e você tem que começar a desenvolver sua aplicação. Você, sabiamente, já verificou o layout das telas que tem que desenvolver e mapeou os componentes que irá precisar para criar sua primeira tela. Todo animado, criou os componente, colocou na linda telinha, está tranquilo, está tudo ali.

Agora, feche os olhos e se imagine no caos! Cheio de fluxos e condições para você visualizar aquele bendito componente que tem que atualizar o layout. Então, dolorosamente, você vai fazer todo esse fluxo para ver aquela mudança necessária, ou, irá fazer algumas gambiarras para poder visualizar mais fácil.

Gambiarras como comentar todo o código de uma página e colocar somente o componente, tirar uma validação para chegar no componente, criar uma pagina nova só para ter acesso ao componente… Já vi muitas dessas gambiarras por ai, e eu mesmo já fiz.

Concordamos que seria bem mais fácil, menos doloroso e mais produtivo se não precisássemos correr toda essa maratona. O ideal é que haver uma forma direta de acessar esse componente, e melhor, isolado da aplicação.

O Storybook pode nos ajudar

Em poucas palavras, o Storybook é uma biblioteca de visualização templates. Nela você pode plugar qualquer projeto de Frontend usando qualquer framework e visualizar os componentes e tudo que tem nele. Assim você pode montar o que quiser, porém, sem a necessidade de inicializar a aplicação.

Sua UI lembra muito aquelas páginas de demonstração dos Frameworks de CSS, com um menu lateral contendo as features e um container com a demonstração dessas features. E é exatamente para isso que ele serve, para demonstrar os componentes da aplicação servindo de documentação visual dos componentes, e, por que não, de outras coisas (fica da criatividade da equipe).

Plugando o Storybook

O Storybook possui um vasto suporte para os mais conhecidos Frameworks de Frontend, conforme tabela abaixo:

https://github.com/storybookjs/storybook#projects

O processo instalação do storybook é bem simples, irei demonstrar com Angular, porque é o que eu mais uso.

O primeiro passo é instalar o storybook e informar o type de aplicação você está usando, qual framework.

 

1
npx -p @storybook/cli sb init --type angular

 

O Storybook/cli vai fazer toda a configuração para você começar a usar com tranquilidade. No final das contas o que ele faz?

Instalação do Storybook para Angular
  • Instala as dependências do Storybook;
  • Cria os arquivos de configuração de inicialização, do registro dos addons e a configuração do typescript(tsconfig) e os typings ;
  • Cria umas stories de demonstração na pasta src/stories;
  • Adiciona os scripts de iniciar o server e build o storybook no package.json;
Arquivos modificados com a instalação do Storybook

Então para rodar esse camarada é só utilizar script que o cli adicionou no package.json;

 

1
yarn storybook

 

O server será iniciado e pronto para ser acessado no endereço

1
localhost:6006

e você poderá ver as stories de demonstração do storybook.

 

Por default o storybook irá ler todos os arquivos terminados com *.stories.ts, mas pode ser configurado, pelo arquivo .storybook/config.js.

Stories de demonstração

Criando nossas próprias stories

Supondo que vamos, por exemplo, definir nossa tipografia, então, podemos criar nossa primeira story. Como se trata do Design System vamos criar o arquivo na pasta src/stories/design-system.

1
2
mkdir ./src/stories/design-system
touch ./src/stories/design-system/typograpy.stories.ts

E vamos adicionar o estilo mais simples possível aqui para nossa tipografia. Editando o src/assets/syles.scss da aplicação.

Vamos destrinchar essa story.

O método storiesOf vai receber o nome da feature que iremos demonstrar e para cada demonstração precisamos definir uma story com o método add, que também recebe um nome para essa story.

Além do nome, o método add recebe uma função que irá retornar nossa story. Esta story é um objeto que possui as propriedades template e styles.

template que contém o html que será renderizado no pelo server do Storybook. Nele, você pode escrever estuturas para demonstrar os componentes ou mesmo as classes de css do Design System da aplicação, neste caso está usando as classes h1, h2 e h3 vindas do styles.scss da aplicação. Você pode também usar as classes de css definidas na propriedade styles,se for necessário criar alguma.

Habemus, primeira story

Resumindo, definimos um template html que está usando o css da aplicação e o da story. Para usar os componentes da aplicação é o mesmo princípio, porém temos duas maneiras de criar stories para os componentes: via declaração de template ou declaração de componente.

A declaração de template nós já vimos faz, para componentes é um pouco diferente, mas nada complicado. Basta importar o component e declarar na propriedade component. Como sempre, temos que passar algum Input para o component, por isso já estou incluindo inputs para essa story.

A story possui uma propriedade props que ela fará a comunicação da story com o component, passando todas as propriedades necessárias para o funcionamento do componente.

Nosso componente é bem simples, ele recebe dois Inputs e faz o bind no template.

Agora se for necessário usar o template para demonstrar um componente, ao invéz de utilizar a propriedade component, a coisa fica um pouco diferente. É necessário definir módulo e injetar no story, isso por que o Storybook cria um módulo dinâmico por contexto de stories. Então para utilizar um componente em um módulo é necessário declará-lo.

Quem é responsável por criar este módulo é o moduleMetadata que herda, não diretamente, da interface NgModule do Angular. Depois de criado basta injetar na story pelo método addDecoratorEsta injeção de dependência será usada em todas as stories deste contexto.

Injeções de dependências

moduleMetadata é uma grande sacada do Storybook, que nele podemos fazer nossas injeções de dependências de componentes, serviços e módulos auxiliares. Lembrando que a intenção é fazer nossas peças de Lego o mais independente possível da aplicação, não conseguimos fugir de termos serviços e outros componentes utilizados no componente demonstrado, para montar peças maiores e mais reutilizáveis.

Da mesma maneira que fazemos as injeções de dependências no TestBed quando vamos testar o componente podemos fazer praticamente a mesma coisa. É possível injetar os serviços reais ou fake, somente para não termos problemas de excução ou para não precisarmos passar por alguma integração da aplicação (isso é muito util!).

Aqui temos bastante coisa interessante:

  • O componente app-foobar, que é da aplicação;
  • O componente mat-icon, do material;
  • Injetamos o serviço FoobarService, que é bem simples;
  • Injetamos o serviço ComplexService, que o nome ja diz, é complexo e vamos mockar esse cara;

Temos aqui as injeções de dependências necessárias para que nosso componente possa ser apresentado. Como comentei anteriormente é bem parecido com o que fazemos para testar um componente.

Por ordem atribuições:

  • Imports -> do módulo do MatIconModule para satisfazer a dependência do mat-icon;
  • Declarations -> do componente a ser demonstrado, SomeComponent, e o componente FoobarComponent reusado no template do app-some;
  • Provides -> do FoobarService e o mock do ComplexService;

Capturando os eventos de Output do Componente

Agora a única coisa que falta para terminarmos de fazer uma story de um componente real é conseguir capturar os eventos emitidos pelos componentes. Sim, temos como fazer isso.

Da mesma maneira que enviamos os propriedades de Input para o componente, conseguimos capturar os eventos de Output deles. Isso é mais uma sacada sensacional do Storybook.

Quando se pensa em desenvolver um componente temos que validar o comportamento do mesmo. Fazemos isso com teste — nem todos fazem — mas é possivel ter essa verificação no Storybook.

Por default temos instalados alguns addons, como é possível ver nas stories iniciais. Lá temos demostração de Notes, Links, e a super útil Action!

O Addon Action nos permite, justamente, fazer a captura de eventos de um específico Output do componente e printar o resultado na tab Action Loggerdo Storybook.

Voltando à stories default que ganhamos ao instalar o Storybook. Lá temos uma story demonstrando o uso da action, e do Notes também.

O componente Button possui um Output onClick, que emite um evento, ao clicar. Esse evento será capturado e o valor emitido será logado na tabAction Logger.

Você pode ter achado estranho essa tela do Storybook. É que ela já está turbinada com vários Addons que nos ajudam na produtividade e organização do nosso show room de componentes.

O gif da demonstação do action é de um projeto que eu fiz para demonstrar algumas features do Storybook. Lá você poderá consultar a forma de configuração deles além da demonstração do funcionamento. Você pode ver no meu Github!

Addons — Turbinando suas Stories

O Storybook possue vários addons para salvar nossa pele na hora de demonstrar nossos componentes. Uns são para organização de demonstração de código, mas eles podem realmente salvar o dia. Você pode conferir no repositório do Storybook mais detalhadamente.

Vou destacar alguns que uso muito e outros que eu sempre configuro em qualquer projeto e você pode ver o funcionamento deles no meu projeto:

  • Backgrounds -> Troca a cor do background da story, é excelente para aquele componente que fica num background zebrado;
  • Console -> Redireciona todo console.log para a story;
  • Knob -> Habilita a modificação das props da story em tempo real;
  • ViewPort -> Possibilita trocar o viewport da story, assim checamos a responsividade do componente;
  • StorySource -> Adiciona a tab Story para mostrar o source code da story;

Instalando um Addon

A instalação do addon é bem simples e em 2 a 3 etapas, em cada add-existe as instruções, mas resumindo são:

A primeira etapa é a instalação do pacote:

 

1
yarn add -D @storybook/addon-nome-do-pacote

 

O registro do addon no arquivo

1
.storybook/addons.js

 

1
2
import '@storybook/addon-nome-do-pacore/register';
//E se necessário a configuração no arquivo .storybook/config.js

Como eu posso te ajudar

Eu desenvolvi um extensão para o vscode contendo alguns snippets para facilitar a minha vida e da minha equipe na implantação do Storybook, talvez possa lhe ajudar também! E só procurar por Storybook Snippetsno menu de extensões do vscode que já está no topo da pesquisa.

Posso te ajudar também tirando dúvidas no uso!

Conclusão

O Storybook é uma ferramenta que eu venho usando há quase 2 anos tanto para React, por onde eu conheci, quando para Angular, e vem me ajudado muito nas entregas da minha equipe.

Podemos, sem medo, parelelizar tarefas para entregar uma feature que, a princípio, demoraria pela interdependência de criação de componentes.

Além disso reduziu exponencialmente o retrabalho de criação de componentes, pois todos os componentes compartilhados estão documentados pelo Storybook.

Ficou muito mais fácil debuggar e atualizar o funcionamento de um componente sem a necessidade de fazer integrações com a aplicação para conferir o comportamento.

A comunidade vem mantendo uma página de tutorial bem interessante também de se conferir.

 

Sobre o autor

Felipe Norato

Uma pessoa que gosta de escrever código para resolver a vida das pessoas e tocar guitara de vez em quando. Apreciador de séries e filmes, assim com um código bem feito e performático.

Twitter: @fnoratol
Github: norato
Medium: @felipenoratolacerda