Se você já tentou criar uma biblioteca de componentes pro seu sistema, você com toda certeza já alterou um componente que quebrou várias páginas e quando te perguntaram quem foi...
Pra eliminar esse e outros problemas, como não saber se um componente existe, como funciona ou em que página você pode ver um exemplo dele funcionando; existe o Storybook.
O Storybook se denomina como "Um explorador de componentes UI para desenvolvedores front-end". Isso quer dizer que ele serve para gerar várias histórias dos nossos componentes, assim como a documentação deles, para facilitar a exploração visual dos nossos componentes.
Então, vamos criar passo-a-passo essa biblioteca de componentes.
Preparação
Na época que esse guia foi preparado, foram usadas as seguintes tecnologias:
| tecnologia | versão | instalação | 
|---|---|---|
| Node.js | 11.6.0 | como instalar | 
| NPM | 6.13.4 | Já vem com o Node.js | 
| Angular CLI | 8.3.21 | como instalar | 
Todo o código desse projeto está no GitHub, então, caso você se perca em qualquer parte, pode fazer uma comparação direta:
      
      
        klauskpm
       / 
        angular-storybook
      
    
    Repositório para ensinar a usar Storybook com Angular.
⚠️ Caso você já saiba gerar uma biblioteca, você pode pular para a sessão Instalando o Storybook ⚠️
Gerando o projeto
Usando o Angular CLI, vamos criar um projeto chamado angular-storybook e uma biblioteca chamada storybook-ui:
ng new angular-storybook
# dentro do projeto angular-storybook
ng g lib storybook-ui --prefix ui # versão curta de ng generate library
Já temos o projeto para usar nossos componentes, e temos a biblioteca onde vamos desenvolver eles. A biblioteca já vem com um componente pronto, mas não vamos usar ele. Então, vamos até a pasta /projects/storybook-ui/src/lib/ e deletamos tudo de lá. Nessa mesma pasta vamos criar o módulo e componente simple-button.
# dentro da pasta /projects/storybook/src/lib
ng g m simple-button # versão curta de ng generate module
ng g c simple-button --export # versão curta de ng generate componente
E vamos dar uma cara de botão para o nosso componente:
import { Component, Input } from '@angular/core';
@Component({
  selector: 'ui-simple-button',
  template: `
    <button>{{text}}</button>
  `,
  styles: [``]
})
export class SimpleButtonComponent {
  @Input() text = 'clique aqui';
}
Agora, vamos no arquivo /projects/storybook/src/public_api.ts e substituir todo o conteúdo desse arquivo por:
export * from './lib/simple-button/simple-button.component';
export * from './lib/simple-button/simple-button.module';
Para usar esse componente precisamos gerar o arquivo final da biblioteca:
ng b storybook-ui # versão curta de ng build
Reescrever o /src/app/app.component.html:
Ola Mundo!
<ui-simple-button></ui-simple-button>
E adicionar o SimpleButtonModule ao /src/app/app.module.ts:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { SimpleButtonModule } from 'storybook-ui';
import { AppComponent } from './app.component';
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    SimpleButtonModule // modificado
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
Por último, vamos servir nossa aplicação e ver como ela está no http://localhost:4200 :
ng s # versão curta de ng serve angular-storybook
Pode comparar o seu progresso com a tag v1.2 do repositório
Instalando o Storybook
O Storybook tem um guia de como fazer a instalação em um projeto Angular e o jeito mais fácil é só usando uma única linha:
npx -p @storybook/cli sb init --type angular
Executando essa linha no seu projeto, ele:
- instala todas as dependências necessárias
 - adiciona os scripts 
storybookebuild-storybookno seu package.json - cria os arquivos de configuração pro Storybook
 - cria as histórias de exemplo no seu projeto principal
 
Para ver o Storybook em ação, é só rodar o comando:
npm run storybook
Tudo bonito, tudo rodando. Mas, a configuração do Storybook está apenas pro seu projeto principal, e não para a sua biblioteca. Além disso, você sabe o que foi adicionado e para que? Então vamos voltar no tempo e seguir de forma manual.
Fazendo a instalação manualmente
1) Instale as dependências
npm install @storybook/angular babel-loader @babel/core --save-dev
2) Adicione os scripts de npm
{
  "scripts": {
    "storybook": "start-storybook -p 6006",
    "build-storybook": "build-storybook"
  }
}
O script storybook vai executar o start-storybook para exibir nossas histórias no http://localhost:6006. O build-storybook vai executar o build-storybook que vai gerar os arquivos estáticos do Storybook na pasta storybook-static.
Você pode definir o diretório final mudando o comando
build-storybookporbuild-storybook -o /dist/storybook, colocando os arquivos estáticos no mesmo diretório que os builds gerados pelo seu projeto.
3) Crie o arquivo de configuração
É esse o arquivo que o Storybook vai usar para saber onde ele pode procurar as nossas histórias e como identificar os arquivos. No caso, vamos procurar arquivos com .stories.ts neles, dentro das pastas src e projects.
Crie o arquivo .storybook/config.js com o seguinte conteúdo:
import { configure } from '@storybook/angular';
configure([
  require.context('../src', true, /\.stories\.ts$/),
  require.context('../projects', true, /\.stories\.ts$/)
], module);
4) Configure o Storybook para funcionar com TypeScript
Como o @storybook/angular usa o ForkTsCheckerWebpackPlugin, precisamos criar o arquivo .storybook/tsconfig.json:
{
  "extends": "../tsconfig.json",
  "exclude": [
    "../src/test.ts",
    "../src/**/*.spec.ts",
    "../projects/**/*.spec.ts"
  ],
  "include": [
    "../src/**/*",
    "../projects/**/*"
  ]
}
5) Escreva sua história 🎉
Finalmente! Agora vamos criar nossa própria história e ver como ela se comporta.
Dentro da pasta do nosso componente simple-button, vamos criar o arquivo index.stories.ts com o conteúdo a seguir:
import { SimpleButtonComponent } from "./simple-button.component";
export default {
  title: 'UI | Button'
};
export const withDefaultValues = () => ({
  component: SimpleButtonComponent
});
export const withText = () => {
  return {
    component: SimpleButtonComponent,
    props: {
      text: 'Ola'
    }
  }
};
Essa é uma das formas que podemos escrever as histórias. Ela é chamada de CSF (Component Story Format). Também temos a StoriesOf API e o MDX Syntax, que está por vir. Como o CSF é um adição nova no Storybook, boa parte dos exemplos da internet vão estar usando o StoriesOf API.
Dessa forma estamos falando que temos o componente Button, dentro do agrupador UI, com as histórias "With Default Values" e "With Text".
UI
└── Button
    ├── With Default Values
    ├── With Text
6) Rode o projeto
Rode o projeto com o npm run storybook e veja o resultado final:
Pode comparar o seu progresso com a tag v1.3 do repositório
Próximos passos - addons
Agora que você aprendeu como configurar o Storybook e escrever uma história, você pode melhorar a qualidade das suas histórias com simples pluggins, chamados de addons.
Por exemplo, com o addon de actions você pode adicionar logs para ações, como clicks, e ouvir o que eles estão enviando. Com o addon de knobs você pode expor @Inputs do seu componente e altera-los na hora.
Pra não ficar só na explicação e sonhos, vamos montar ele agora. É muito fácil.
1) Instale as dependências
Além dos pacotes óbvios do knobs e do actions, precisamos também instalar o pacote do addons, que vai ser responsável por carregar os addons no Storybook.
npm install --save-dev @storybook/addons @storybook/addon-knobs @storybook/addon-actions
2) Crie o arquivo de configuração dos addons
Crie o arquivo .storybook/addons.js com a seguinte configuração:
import '@storybook/addon-knobs/register';
import '@storybook/addon-actions/register';
A ordem que você importa eles é importante. Ela vai dizer a ordem em que esses addons vão aparecer nos paineis
3) Aplique os addons na sua história
No nosso caso, vamos usar o knobs para expor o @Input text e o actions para exibir uma mensagem ao clicar no botão. Como vamos lidar com um evento e não uma propriedade, não podemos mais usar o component na história withText, pois o props só define propriedades e não eventos. Precisamos usar o template, mas para usarmos o template, precisamos definir o módulo com o componente SimpleButtonComponent.
No final das contas, o nosso index.stories.ts do SimpleButtonComponent vai ficar assim:
import { SimpleButtonComponent } from "./simple-button.component";
import { text, withKnobs } from '@storybook/addon-knobs';
import { moduleMetadata } from '@storybook/angular';
import { action } from '@storybook/addon-actions';
export default {
  title: 'UI | Button',
  decorators: [
    withKnobs,
    moduleMetadata({declarations: [SimpleButtonComponent]})
  ],
};
export const withDefaultValues = () => ({
  component: SimpleButtonComponent
});
export const withText = () => {
  return {
    template: `
        <ui-simple-button
          [text]="text"
          (click)="click($event)"
        ></ui-simple-button>
    `,
    props: {
      text: text('Text', 'Ola'),
      click: action('Clicou')
    }
  }
};
E quando rodarmos o Storybook:


Pode comparar o seu progresso com a tag v1.4 do repositório
Conclusão
Agora, você sabe como...
✅ Instalar e configurar o Storybook
✅ Criar histórias para componentes
✅ Instalar e configurar addons
Você não vai ter mais problemas em relação ao que sua aplicação tem ou não tem, e o desenvolvimento vai seguir com mais confiança e agilidade, por poder testar as mudanças em diversos cenários.
Se você se interessou pelo Storybook e quer saber o que mais ele pode fazer, você pode começar a ver como...
❗ Aprender o que compõe uma história
❗ Exportar e deployar arquivos estáticos das histórias
❗ Tematizar o Storybook
🎉 E muito mais
Se você ❤️ esse artigo, não deixe de me seguir e compartilhar com seus colegas. E se achar que tem algo para mudar no artigo, não deixe de comentar!
Te vejo na próxima! 😬






    
Top comments (2)
Valeu Klaus, ganhou um fã carioca!
Valeu mano 😬 !