Flutter — Construindo um Projeto Boilerplate perfeito do zero
Crédito: Nguyễn Thành Minh (Desenvolvedor Android)
Todos nós já passamos por isso - o que quero dizer é que todos nós tentamos construir um projeto clichê para o trabalho ou como um projeto pessoal. Um bom projeto clichê nos poupará muito tempo resolvendo problemas comuns como chamar APIs, processar dados de bancos de dados e talvez o mais importante — tornar nosso código organizado e consistente para que as pessoas possam ter mais facilidade em entender nosso código. Esta série destina-se a compartilhar um projeto padrão que construí, usei e mantive nos últimos dois anos. Além disso, compartilharei minha abordagem para codificá-lo, bem como soluções para problemas comuns que possam surgir. Dito isso, esta é a parte 1: Explorando o Projeto.
Veja no Github
1. Características
Funcionalidades construídas neste projeto:
- Arquitetura: Arquitetura Limpa
- Gerenciamento de estado: flutter_bloc
- Navegação: auto_route
- DI: get_it , injetável
- API REST: di
- GraphQL: artemis , graphql_flutter
- Banco de dados: objectbox
- Preferências compartilhadas: crypto_shared_preferences
- Classe de dados: congelado
- Lint: dart_code_metrics , flutter_lints
- CI/CD: Github Actions, Bitbucket Pipelines
- Teste de Unidade: mocktail , bloc_test
- Paginação: infinite_scroll_pagination
- Utilitários : rxdart , dartx , assíncrono
- Gerador de ativos: flutter_gen_runner , flutter_launcher_icons , flutter_native_splash
- Outros recursos: solicitações de API com falha na repetição automática, token de atualização,…
Para executar este projeto como pretendido, sua versão do Flutter deve ser (exatamente) 3.3.9 e a versão Melos 2.8.0 deve estar instalada. Se você gostaria de ter uma Convenção Git para sua equipe, você também pode instalar o lefthook . Falarei sobre Melos e Lefthook nas últimas partes da série. Por enquanto, veja como executar o projeto.
Nota: usei VSCode e macOS, então não posso garantir que também funcione no Android Studio ou Windows.
2.1. Instalando Melos
A Arquitetura Limpa exige que dividamos o projeto em vários módulos (pacotes), por isso precisamos de uma ferramenta para gerenciar pacotes — o Melos. Para instalar Melos:
dart pub global activate melos 2.8.0
export PATH="$PATH:<path to flutter>/flutter/bin"
export PATH="$PATH:<path to flutter>/flutter/bin/cache/dart-sdk/bin"
export PATH="$PATH:~/.pub-cache/bin"
Depois de instalar o Melos, você precisará executar o comando make gen_envou dart run tools/gen_env.dart. Esta é uma ferramenta que eu mesmo criei, a fim de criar a envpasta para que possamos declarar segredos como Google API_KEY, credenciais básicas de autenticação, etc. Esta ferramenta irá ler valores no .envarquivo e colocá-los no dart-definesinalizador quando o aplicativo Flutter for executado ou construído.
2.3. Gerando arquivos
Uma vez que temos a envpasta, agora só precisamos executar o comando make sync. Esta é uma abreviação para três comandos:
melos bootstrap
melos run l10n
melos run force_build_all
Em seguida, o comando melos run l10najuda a gerar a classe Sa partir dos .arbarquivos nos resourcesmódulos.
Por fim, o comando melos run force_build_allajuda a gerar os arquivos .g.dart, .freezed.dart, etc. em todos os pacotes que possuem a biblioteca build_runner.
Agora, corra make run_devpara rodar o app e aproveite!
3. Arquitetura do Projeto
Ao todo, temos 6 módulos (pacotes)
- Aplicativo
- Domínio
- Dados
- Recursos
- Compartilhado
- Inicializador
3.1. O módulo de aplicativo
É aqui que codificaremos nossa interface do usuário e o Bloco. Além disso, é onde armazenaremos nossos recursos como cores, dimensões e estilos de texto. Também é aqui que declararemos nossa função main() como um ponto de entrada para a execução de nosso aplicativo.
Ambas as pastas app_icone splashcontêm os arquivos app-icon.yamle splash.yaml, portanto, podemos configurar o ícone do aplicativo e a tela inicial conforme as instruções das bibliotecas flutter_launcher_icons e flutter_native_splash .
A apppasta contém AppBloc, que é um Bloco fornecido em MaterialApp, um local de onde todas as telas do app podem recuperar dados, ou seja; é como um bloco compartilhado para todas as telas. Você pode usar AppBlocpara tarefas que precisam atualizar a interface do usuário de todas as telas, como configuração de idioma, alternância de modo escuro/modo claro.
A pasta é onde codificaremos as classes base , basecomo BasePageState, e .BaseBlocBaseEventBaseState
A pasta shared_viewé onde codificarei a interface do usuário compartilhada entre várias telas e poderá ser usada para outros projetos. Por exemplo: app_text_field, circle_imagesão visualizações de grupo comuns vistas nas telas de Login e Cadastro.
A pasta common_viewé onde codificarei a interface do usuário compartilhada entre várias telas e poderá ser usada para outros projetos. Por exemplo, common_dialog, common_app_bar, common_scaffoldpodem ser reutilizados em muitos projetos, embora possamos ajustá-los um pouco para corresponder ao estilo.
A pasta configé onde chamarei funções de configuração para o módulo de aplicativo, comoFirebase.initializeApp()
A pasta dié para configuração de DI para o módulo app.
A pasta exception_handlercuidará de todas as exceções no projeto.
A pasta helpercontém classes Helper usadas exclusivamente para o módulo app.
A pasta navigationé onde declararemos as telas, bem como as caixas de diálogo e as planilhas inferiores usadas no aplicativo.
A pasta resourceé onde declararemos recursos para a interface do usuário, como cores, dimensões e estilos de texto.
A pasta uié onde codificarei a interface do usuário e o bloco para cada tela.
A pasta utilsé onde codificarei as funções utils usadas exclusivamente para o módulo app.
3.2. O módulo de domínio
Semelhante ao módulo de aplicativo, as pastas confige diservem a propósitos semelhantes no módulo de domínio.
A pasta entitycontém entidades de classe como User e Booking.
A pasta navigationcontém a AppNavigatorclasse, que é responsável por push, replacee poppelas telas.
A pasta repositoryé onde declararemos as classes do Abstract Repository no projeto.
A pasta usecaseé onde declararemos os Casos de Uso no projeto.
3.3. O módulo de dados
Da mesma forma, as pastas confige diservem para o mesmo propósito aqui.
A pasta graphqlcontém .graphqle schema.graphqlse o seu projeto usa GraphQL. O arquivo build.yamlé usado para configurar os arquivos gerados relacionados ao GraphQL.
A pasta repositorycontém classes de Implementação de Repositório. Ele também contém várias pastas:
converter: para codificar classes do Convertermapper: para codificar classes Mapper que são usadas para mapear modelos de dados em Entidadesmodel: para codificar classes de modelo de dadossource: para codificar classes base como RestApiClient, GraphQlApiClient, bem como fornecer fontes de dados no projeto como AppApiService, AppDatabase, AppSharedPreferences, LocationDataSource
Este é um módulo simples, contém apenas .arbarquivos que fornecem Strings para localização. Este módulo é injetado em outros dois módulos, appe domainassim as classes UI, Bloco, Entidade e Caso de Uso podem utilizar.
3.5. O módulo compartilhado
Como o nome sugere, este módulo fornece constantes, classes de exceção personalizadas, classes auxiliares, mixins e funções utilitárias para outros módulos usarem.
3.6. O módulo inicializador
Este módulo contém apenas a classe AppInitializer. Esta classe é responsável por reunir todas as configurações de outros módulos em uma init()função; A main()função só precisa chamar esta init()função para recuperar todas as configurações de todos os módulos.
3.7. Outras pastas e arquivos
A pasta .githubé para configurar CI/CD se o seu projeto usar o Github Actions.
A pasta .lefthooke o arquivo lefthook.ymlsão para configurar a convenção Git usando a biblioteca lefthook.
A pasta .vscodeé para declarar as configurações do VSCode usadas para este projeto.
A pasta .envserve para declarar os segredos de cada ambiente.
A pasta toolscontém as ferramentas que criei.
O arquivo analysis_options.yamlé para declarar regras linter de duas bibliotecas flutter_lints e dart_code_metrics .
O arquivo bitbucket-pipelines.ymlé para configurar o CI se o seu projeto usar o Bitbucket Pipelines.
O arquivo makefileacompanha todos os comandos usados no projeto. Por exemplo, o comando make formatajuda a formatar todo o código com .dartextensão de arquivo dentro do projeto. Existem muitos outros comandos como make testo que executa o Unit Test em todos os módulos.
O arquivo melos.yamlé para configuração do Melos.
Conclusão
Por que precisamos criar outro módulo apenas para init config? O que são mapeadores, entidades e classes de caso de uso? Irei abordá-los na segunda parte desta série — a Arquitetura Limpa.





































![O que é uma lista vinculada, afinal? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)