- 🚀 Typescript
- 🚀 Testes
- 🚀 Controle de rotas
- 🚀 Suporte a temas (light/dark)
- 🚀 Design consolidado
- 🚀 Splashscreen
- 🚀 Serviços para HTTP Request e tratamento de erros
- 🚀 Monitoramento de bugs via AppCenter
- 🚀 CI via Gitlab
Este boilerplate possuir uma base sólida para desenvolvimento de aplicativos mobile usando React Native. São fornecidos estrutura de pastas organizadas, dependências comuns usadas, controle de rotas de navegação, configuração de testes usando Jest e utilitários.
- NVM
- Yarn
- Cocoapods
- JDK 11
- Xcode
- Android SDKs (Recomendado instalar via Android Studio)
Há duas maneiras de usar esse boilerplate.
- Clonando o repositório e usando a react-native-rename ferramenta para troca o nome do app conforme o projeto que será desenvolvido.
- Inicializar um novo projeto react native pela ferramenta oficial e copiar os demais arquivos desse repositório, excerto o
package.json
,app.json
,android/
eios/
, e por final copiar as dependências que não estão inclusas no projeto oficial. Lembrando que algumas delas são necessárias aplicar configurações especias nas pastas designado de cada sistema operacional (android/
eios/
):
As variáveis de ambiente devem ser colocadas no arquivo .env
, um exemplo de como definir as variáveis usadas está localizado em .env.example
, lembrando de que sempre que criar uma nova variável no projeto definir ela no .env.example também, para que outros membros possam ter conhecimento dela. Algumas regras para nomenclatura de variável:
- Devem começar com "RN"
- Usar estilo de nome de variável snake case
- Usar somente letras maiúsculas e sem acentuação
Exemplos:
RN_MINHA_VARIAVEL
RN_USER_ID
RN_PASS
Por padrão todo projeto tem quatro variáveis:
RN_BASE_URL
: Informar a URL base referente a URL de um serviço web que em algum momento o cliente pode ser redirecionado de dentro do appRN_BASE_URL_API
: Informar a URL base referente ao consumo de uma web API dedicado ao appRN_ENV
: O ambiente que está sendo usado, como, por exemplo:development
,test
,staging
,production
RN_FEATURES_OFF
: Informar quais funções vão ser desativado no app, essa env é opcional
Para criar uma splashscreen você deve usar o generate-bootsplash, informado o caminho para a logo da splashscreen e a cor de fundo, exemplo:
yarn react-native generate-bootsplash src/assets/images/logoSplashScreen.png --background-color=ffffff --logo-width=100 --assets-path=src/assets --flavor=main
Uma segunda tela de abertura pode ser configurada em src/screens/SplashScreen
(Recomendado deixar como Splashscreen nativo, para não ter efeito de "piscada de tela" entre as transições), essa não está limitada a apenas utilização de uma imagem, elementos como barra de carregamento podem ser adicionando. Essa tela é carregada após o SplashScreen nativo do sistema operacional (Android/iOS), essa tela em questão deve ser usado para esperar o carregamento ou verificação de dados do app, tal como se o usuário está autenticado.
Para mais informações de padrões da SplashScreen veja em Android Guide - Splash screens.
Usamos o AppCenter para gerar build e monitorar crash, devido isso você deverá fornecer o "APP SECRET" do projeto registrado no AppCenter em appcenter-config.json
.
O boilerplate é projetado para utiliza Styled Component e React Native Paper, a customização do app é feito através de configurações de estilo localizado em src/theme
.
A principal dele é as cores (src/theme/colors.ts
), nele está contido as cores a serem consumido no app, usado o sistema de cores do Material Design, devido isso é possível inclusive usar a ferramenta de customização de tema do Material Design: https://material.io/resources/color/. Caso o App tenha uma variente de modo escuro, suas cores podem ser definido em src/theme/colors.dark.ts
.
📦(root boilerplate)
┣ 📂.vscode
(Configurações e extensões para o VSCode)
┣ 📂android
(Configurações e código nativo referente ao Android)
┣ 📂ios
(Configurações e código nativo referente ao iOS)
┣ 📂patches
(Correções e melhoria dos pacotes usados no projeto)
┣ 📂src
(Pastar principal do projeto)
┃ ┣ 📂assets
(Arquivos estáticos)
┃ ┃ ┣ 📂fonts
(Fontes)
┃ ┃ ┣ 📂images
(Imagens .png, .jpg, etc)
┃ ┃ ┗ 📂svg
(SVGs .svg)
┃ ┣ 📂components
(Componentes usado no app)
┃ ┃ ┣ 📂[Nome do componente]
┃ ┃ ┃ ┣ 📜index.tsx
(Implementação do componente)
┃ ┃ ┃ ┣ 📜index.spec.tsx
(Teste do componente)
┃ ┃ ┃ ┗ 📜styles.ts
(Folha de estilo do componente)
┃ ┣ 📂configs
(Grupo de variáveis de configuração destinado a uma lib ou parte do app)
┃ ┣ 📂contexts
(Contexto)
┃ ┃ ┣ 📜AllProviders.tsx
(Importação de todos os Contextos usado no app)
┃ ┃ ┣ 📜[Nome do Contexto]Context.spec.tsx
(Implementação de controle de um contexto)
┃ ┃ ┗ 📜[Nome do Contexto]Context.tsx
(Testes de um contexto)
┃ ┣ 📂hooks
(Hooks compartilhado entre telas)
┃ ┃ ┣ 📜Use[Nome do Hook]Context.spec.tsx
(Implementação de um hook)
┃ ┣ 📂routes
(Gerenciamento de rotas)
┃ ┃ ┣ 📜AppNavigator.tsx
(Gerenciamento principal de rotas do app - usúario autenticado)
┃ ┃ ┣ 📜AuthNavigator.tsx
(Gerenciamento de rotas de um usúario não autenticado)
┃ ┃ ┗ 📜MockedNavigator.tsx
(Gerenciamento de rotas para testes)
┃ ┣ 📂screens
(Telas usado no App)
┃ ┃ ┣ 📂App
(Telas principal do app - usúario autenticado)
┃ ┃ ┃ ┣ 📂[Nome do conjunto de tela]
┃ ┃ ┃ ┃ ┗ 📂[Nome da Tela]
┃ ┃ ┃ ┣ 📂[Nome da Tela]
┃ ┃ ┃ ┃ ┣ 📜index.tsx
(Implementação da da tela)
┃ ┃ ┃ ┃ ┣ 📜index.spec.tsx
(Teste da tela)
┃ ┃ ┃ ┃ ┣ 📜styles.ts
(Folha de estilo da tela)
┃ ┃ ┃ ┃ ┣ 📂components
(Componentes usado na tela apenas)
┃ ┃ ┃ ┃ ┃ ┣ 📂[Nome do componente]
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜index.tsx
(Implementação do componente)
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜index.spec.tsx
(Teste do componente)
┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜styles.ts
(Folha de estilo do componente)
┃ ┃ ┣ 📂Auth
(Telas para o usúario não autenticado)
┃ ┃ ┃ ┗ 📂 [Nome da Tela]
┃ ┃ ┗ 📂SplashScreen
(Tela de carregamento do app)
┃ ┣ 📂services
(Serviços a serem consumido pelo app)
┃ ┃ ┣ 📜api.ts
(Implementação dos métods da Web API)
┃ ┃ ┣ 📜[Nome do Serviço].ts
(Implementação de um novo serviço)
┃ ┃ ┗ 📜[Nome do Serviço].spec.tsx
(Realização do teste de um serviço)
┃ ┣ 📂tests
(Utilitários para teste)
┃ ┃ ┣ 📂actions
(Ações commum realizadas em testes)
┃ ┃ ┣ 📂mocks
(Mocks para teste)
┃ ┃ ┃ ┣ 📜[Nome grupo de Mocks].ts
(Implementação de mocks)
┃ ┃ ┃ ┣ 📜global.ts
(Importação de todos os mocks usado globalmente)
┃ ┃ ┗ 📂responses
(Mocks de request do Axios)
┃ ┃ ┃ ┗ 📜[Nome do método para request na API].ts
(Implementação do mock)
┃ ┣ 📂theme
(Implementação de estilo do app)
┃ ┃ ┣ 📜colors.dark.ts
(Cores do app no modo dark)
┃ ┃ ┣ 📜colors.ts
(Cores do app)
┃ ┃ ┣ 📜common.ts
(Folha de estilo commun detro do app)
┃ ┃ ┣ 📜dimensions.ts
(Dimensões commun dentro do app)
┃ ┃ ┗ 📜index.ts
(Importação de todo o tema)
┃ ┣ 📂typings
(Somente implementação de tipagem para o Typescript)
┃ ┣ 📂utils
┃ ┃ ┣ 📜[Nome do Utilitário].ts
(Importação do utilitário)
┃ ┃ ┗ 📜[Nome do Utilitário].spec.tsx
(Teste do utilitário)
┃ ┗ 📜App.tsx
┣ 📜.editorconfig
(Configurações de editor de código)
┣ 📜.env.example
(Exemplo de configurações de variável de ambiente)
┣ 📜.env.test
(Configurações de variável de ambiente para teste)
┣ 📜.env
(Configurações de variável de ambiente para o app)
┣ 📜.eslintrc.js
(Configurações do ESlint)
┣ 📜.gitlab-ci.yml
(Configurações pipeline do Gitlab)
┣ 📜.gitignore
┣ 📜.nvmrc
(Configurações da versão do Node)
┣ 📜.prettierrc.js
┣ 📜.ruby-version
(Configurações da versão do Roby)
┣ 📜.watchmanconfig
┣ 📜app.json
┣ 📜appcenter-config.json
┣ 📜appcenter-post-clone.sh
┣ 📜appcenter-pre-build.sh
┣ 📜babel.config.js
(Configurações do babel)
┣ 📜Gemfile
┣ 📜index.js
┣ 📜jest.config.js
(Configurações do Jest para testes)
┣ 📜jestSetupFile.js
┣ 📜metro.config.js
┣ 📜package.json
(Configurações em geral do pacote)
┣ 📜react-native.config.js
┣ 📜tsconfig.json
(Configurações do Typescript)
┗ 📜yarn.lock
O projeto usa ESlint, Prettier e EditorConfig, para controlar padrões de estilo. Abaixo estão algumas regras que ainda não podem ser aplicadas via uma dessas ferramentas.
- Separar importação por contexto, sendo as primeiras importações do react e react native, depois do node module, e em seguida por grupo de pastar e por último importações com caminho relativo.
❌ Não fazer
import { alertSpy } from '@tests/actions/alertSpy';
import React from 'react';
import { mockedNavigate } from '@tests/mocks/rnNavigation';
import Home from './index';
import MockedNavigator from '@routes/MockedNavigator';
import { act, cleanup, render } from '@testing-library/react-native';
✅ Fazer isso
import React from 'react';
import { act, cleanup, render } from '@testing-library/react-native';
import { alertSpy } from '@tests/actions/alertSpy';
import { mockedNavigate } from '@tests/mocks/rnNavigation';
import MockedNavigator from '@routes/MockedNavigator';
import Home from './index';
- Usar CamelCase em nomenclatura de variável. Permitido fuga do padrão quando trata de uma variável dentro de um corpo de um HTTP response/request.
❌ Não fazer
const firt_Name: string = 'João';
const LAST_NAME: string = 'Paulo';
✅ Fazer isso
const firtName: string = 'João';
const lastName: string = 'Paulo';
- Informar o tipo no
useState
.
❌ Não fazer
const [isFocus, setIsFocus] = useState(false);
const [currentValue, setNewValue] = useState('');
✅ Fazer isso
const [isFocus, setIsFocus] = useState<boolean>(false);
const [currentValue, setNewValue] = useState<string>('');
- Passando atributos no Styled. Atributos que utilizam as
props
, devem terreturn
em seu corpo pois a extensão do VSCode do styled buga sem esse padrão de estilo de código.
❌ Não fazer
export const ContainerTextInput = styled(TextInputComponent).attrs((props) => ({
mode: props.mode || 'outlined',
autoCapitalize: props.autoCapitalize || 'words',
placeholderTextColor:
props.placeholderTextColor || props.theme.colors.placeholderText,
dense: true,
}))``;
✅ Fazer isso
export const ContainerTextInput = styled(TextInputComponent).attrs((props) => {
return {
mode: props.mode || 'outlined',
autoCapitalize: props.autoCapitalize || 'words',
placeholderTextColor:
props.placeholderTextColor || props.theme.colors.placeholderText,
dense: true,
};
})``;
Para testes unitários está sendo utilizado biblioteca Jest e para escrever os testes é necessário criar arquivos .spec.ts
/ .spec.tsx
dentro do mesmo diretório em que se encontra o fragmento de código.
Há alguns utilitários para facilitar a criação de testes, o primeiro deles é criar uma copiar mockado dos retornos da API localizado em src/tests/responses/
, veja o exemplo de como criar um espelho de um request em src/tests/responses/exampleMethodName.ts
.
Caso tenha um teste que envolva alerta, há um utilitário em src/tests/actions/alertSpy.ts
, como ele você pode selecionar um botão em específico pelo nome:
import { alertSpy, onAlertActions } from '@tests/actions/alertSpy';
// ... //
const { pressAlertButton } = onAlertActions();
describe('Home Screen', () => {
afterEach(() => {
cleanup();
alertSpy.mockClear();
});
// ... //
it('should ...', async () => {
// ... //
await act(async () => {
await waitFor(() => alertSpy);
expect(alertSpy).toHaveBeenCalledTimes(1);
expect(alertSpy).toHaveBeenLastCalledWith(
'Falha!',
'Não foi possível obter dados',
expect.anything(),
expect.anything(),
);
await pressAlertButton('Confirmar');
});
// ... //
});
});
Para carregamento correto dos render deve estar atento que ao realizar os testes de tela, deve ser usado o MockedNavigator
:
import MockedNavigator from '@routes/MockedNavigator';
import NameScreen from './index';
// ... //
describe('Name Screen', () => {
// ... //
it('should render correctly', async () => {
render(<MockedNavigator component={NameScreen} />);
await act(async () => {});
});
// ... //
});
Agora caso precise apenas que faça o carregamento do tema em um componente pode ser usado o shadowTheme
:
import { shadowTheme } from '@tests/actions/styledTheme';
import NameComponent from './index';
// ... //
describe('Name Component', () => {
// ... //
it('should render correctly', async () => {
render(shadowTheme(<NameScreen placeholder="Test placeholder" />));
await act(async () => {});
});
// ... //
});
Os mocks a serem consumido no projeto podem ser criados em src/tests/mocks/
sendo separados em arquivos, de acordo com seu contexto ou biblioteca facilitando a manutenção. Os mocks que serão consumidos globalmente devem ser importados em src/tests/mocks/global.ts
, os demais devem ser importando quando necessário no arquivo de spec do teste.
- react-navigation: Controle de rotas de navegação
- react-native-paper: UIKit com vastar quantidade de componentes pronto, personalizável e seguindo o padrão de UX do Material Design.
- react-native-vector-icons: Pacotes de ícones
- react-native-bootsplash: Implementar nativamente uma SplashScreen usando as APIs oficial de cada sistema operacional
- react-native-element-dropdown: Implementar um menu dropdown funcional e customizado
- react-native-mask-text: Adicionar mascara nos componentes de Input
- react-native-tiny-toast: Um componente de Toast que funcionar em qualquer sistema sem permissão especial
- react-native-calendars: Implementar visualização de calendário e DatePicker personalizável
- react-native-webview: Componente para adicionar WebView nativamente
- react-native-linear-gradient: Componente para criar gradientes
- react-native-skeleton-placeholder: Componente para criar placeholder
- react-native-qrcode-svg: Componente para gerar um QRCode usado SVG
- react-native-confirmation-code-field: Componente para criar telas de código de confirmação com suporte nativo de autocomplete via SMS
- react-native-auth0: Implementação de autenticação direto com o Auth0
- @react-native-firebase/messaging: Notificação via Firebase
- react-native-onesignal: Notificação via OneSignal
- appcenter: Integração com AppCenter
- axios: HTTP Cliente.
- luxon: Formatação de data
- patch-package: Aplicação de correção em pacotes
- react-hook-form: Gerenciamento de formulários
- yup: Validação de dados
- react-native-device-info: Informar dados sobre o dispositivo
- react-native-svg-transformer: Permitir importar arquivos .SVG
- @react-native-firebase/remote-config: Integração com Firebase Remote Config
- react-native-camera: Suporte para usar câmera nativamente do dispositivo
- react-native-keyboard-aware-scroll-view: Evitar problemas de sobreposição do teclado