rn-lib-storybook v1.2.0
ReactNative + Lib + Storybook
O processo para criar uma lib de componente com react native e storybook será detalhado a seguir. Todos os passos aqui descritos foram criados em 26 de outubro de 2022.
Criando um projeto com Expo
npx create-expo-app rn-lib-storybookApós criar seu projeto, vamos adicionar o Typescript. Mude o App.js para App.tsx, e depois execute yarn start. Será perguntado no terminal se você deseja instalar algumas libs de tipagem, aperte y e aguarde a finalização.
Agora abra seu projeto em um emulator para validar a execução do mesmo. Caso ocorra tudo bem, vamos para o próximo passo.
Instalando e configurando o Storybook
npx storybook init --type react_nativeO comando acima inicia o processo de instalação e configuração do storybook no react native. Será perguntado se você deseja instalar o react-native-server, aperte y para aceitar. Ao final do processo, será perguntado se você deseja rodar uma migração para o npm7, aperte n para não aceitar.
Agora abra o arquivo storybook/addons.js e mude todas as importações para /register, ficando assim:
import "@storybook/addon-actions/register";
import "@storybook/addon-links/register";
import "@storybook/addon-knobs/register";Abra seu arquivo App.tsx e remova todo o conteúdo e adicione o código a seguir:
import StorybookUI from "./storybook";
export default StorybookUI;Agora se você executar novamente yarn start verá o storybook sendo executado em seu emulador.
Etapas opcionais, porém do meu gosto
Eu gosto de organizar meus códigos sempre em uma pasta src, por isso, dentro da pasta storybook eu removi todos os components já criados por padrão, criei a pasta src, e dentro a pasta components. Na raiz de src adicionei um arquivo stories.ts, que será responsável por importar os stories para que o storybook possa ler.
Agora você pode adicionar seus components e vê-los no storybook. Lembrando apenas de exportar em seu stories.ts. Mude também a configuração em storybook/index.js para que o storybook use esse arquivo stories.ts.
Bob builder
Antes de configurarmos o bob builder, precisamos na pasta src criar um arquivo index.ts e exportar pelo menos um componente dentro do arquivo para que o bob builder possa usa-lo para configuração.
export * from './components/Button'Vamos utilizar a lib react-native-builder-bob para construir nossa lib de componentes. Execute npx react-native-builder-bob@latest init para configurar a lib. Responda as perguntas conforme abaixo.
❯ npx react-native-builder-bob@latest init
Need to install the following packages:
react-native-builder-bob@0.20.0
Ok to proceed? (y) y
✔ Where are your source files? … src
✔ Where do you want to generate the output files? … lib
✔ Which targets do you want to build? › commonjs - for running in Node (tests, SSR etc.), module - for bundlers (metro, webpack etc.), typescript - declaration files for typechecking
✔ Your package.json has the 'main' field set to 'node_modules/expo/AppEntry.js'. Do you want to replace it with 'lib/commonjs/index.js'? … no
Project rn-lib-storybook configured successfully!Após isso o bob adicionará itens no .gitignore e no package.json. Vamos rodar o comando yarn prepare, e vermos ele quebrar, isso porque precisamos mudar algumas coisas antes.
Em package.json, talvez você vai precisar mudar o script yarn prepare para o valor npx react-native-builder-bob@latest build, isso porque aqui o comando bob não foi encontrado.
Agora substitua todo o conteúdo de tsconfig.json para:
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"noEmit": false
},
"exclude": [
"node_modules",
"dist",
"lib",
"**/*.spec.ts",
"**/*.stories.[tj]sx",
"**/*.test.[tj]sx",
"App.test.tsx",
"App.tsx"
]
}Rode novamente o comando yarn prepare e veja a saída na pasta lib.
Publicando no NPM
Se você for publicar um projeto publico, lembre-se de remover o private: true do package.json.
Execute npm login e npm publish para publicar sua lib.
Testes
Como estamos usando o expo para nosso ambiente, precisamos instalar o jest seguindo a documentação da Expo.
npx expo install jest-expo jest @types/jest --save-devAgora em seu package.json, adicione o script "test": "jest". Também adicione o preset do jest conforme abaixo.
"jest": {
"preset": "jest-expo",
"transformIgnorePatterns": [
"node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg)"
]
}Formatação de código
Vamos instalar algumas libs para auxiliar e padronizar a formatação de código.
npm i --save-dev eslint prettier @react-native-community/eslint-configAgora adicione o código a seguir ao final de seu package.json.
"eslintConfig": {
"extends": "@react-native-community"
}Adicione os seguintes scripts ao package.json.
"lint": "eslint",
"format": "prettier *.{js,tsx} -w"Padronizando Commits
Vamos começar a instalar umas libs e configura-las para nos auxiliar durante o processo de commit.
npm install --save-dev commitizen
npx commitizen init cz-conventional-changelog -D -EAdicione o script "commit": "git-cz" ao seu package.json. Agora adicione os arquivos com git add . e execute npm run commit para testar.
Agora vamos impor que quando um commit acontecer, nós chamemos o npm run commit por padrão. Vamos começar instalando o husky e outras libs.
npm install --save-dev husky
npm install --save-dev @commitlint/{config-conventional,cli}Agora adicione ao final do seu package.json.
"commitlint": { "extends": ["@commitlint/config-conventional"] },
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}Automatizando a entrega de novas versões com GitHub Actions
Antes de iniciar, você precisa criar um token no NPM para que o semantic-release possa publicar sua lib. Após criar o token, adicione-o como uma secret do seu repositório, siga os passos a seguir:
- No GitHub, navegue até a página principal do repositório.
- Sob o nome do seu repositório, clique na guia "Configurações".
- Na barra lateral esquerda, clique em Segredos, depois Actions.
- Na barra direita, clique em "Adicionar um novo segredo"
- Digite um nome para seu segredo na caixa de entrada "Nome".
- Digite o valor para seu segredo, nesse caso colocamos o valor de nosso token.
- Clique em Adicionar segredo.
Faça a instalação do semantic-release.
npm install --save-dev semantic-releaseAgora adicione "semantic-release": "semantic-release" ao scripts em seu package.json. Adicione a final do package.json:
"release": { "branches": [ "main" ] }Crie um arquivo chamado deploy.yml dentro da pasta .github/workflows/deploy.yml e adicione o seguinte conteúdo.
name: Deploy lib
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
with:
persist-credentials: false
- name: Setup NodeJS
uses: actions/setup-node@v3
with:
node-version: 16.x
- name: Use cached node_modules
uses: actions/cache@v1
with:
path: node_modules
key: nodeModules-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
nodeModules-
- name: Install dependencies
run: npm install
env:
CI: true
- name: Lint
run: npm run lint
env:
CI: true
- name: Test
run: npm run test --ci --coverage --maxWorkers=2
env:
CI: true
- name: Build
run: npm run prepare
env:
CI: true
- name: Semantic Release
run: npm run semantic-release
env:
CI: true
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}