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
storybook
ebuild-storybook
no 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-storybook
porbuild-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 @Input
s 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 😬 !