🐒Monorepos
Documentação: Desenvolvendo um Projeto Monorepo em Flutter
1. Introdução ao Monorepo
Um Monorepo é uma estratégia de gerenciamento de repositórios onde todos os módulos e pacotes de um projeto são mantidos em um único repositório. Esta abordagem traz várias vantagens, como facilitar o compartilhamento de código, simplificar a dependência e a gestão de versões e melhorar a colaboração entre equipes.
2. Estrutura do Projeto Monorepo
Neste projeto Monorepo de Flutter, temos uma estrutura de pastas e módulos cuidadosamente planejada para otimizar a reutilização de código, facilitar a manutenção e melhorar a colaboração entre desenvolvedores. A seguir, detalho mais sobre cada pasta:
app_domain:
Descrição: Esta library age como o núcleo da lógica de negócios e contém a definição de todos os domínios, usecases, repositórios e datasources.
Benefícios: Isolar a lógica de negócios desta forma permite que ela seja testada independentemente do resto do aplicativo. Além disso, ela pode ser reutilizada em diferentes aplicações ou módulos que compartilhem a mesma lógica de negócios.
Exemplo da main.dart do app_domain:
library app_domain;
export 'src/domain/repositories/i_repositories.dart';
export 'src/domain/usecases/usecases.dart';
export 'src/external/datasources/datasources.dart';
export 'src/external/models/models.dart';
export 'src/usecases/i_usecases.dart';
app_platform:
Descrição: É onde o aplicativo em si reside. Este módulo liga todas as outras libraries e faz o trabalho pesado de inicialização e execução do aplicativo.
Benefícios: Mantendo o código específico da plataforma separado, fica mais fácil gerir atualizações específicas da plataforma e lógicas de negócios universais.
common_dependencies:
Descrição: Esta library serve como um catálogo centralizado para todas as dependências comuns (bibliotecas externas, recursos, constantes) que são usadas em todo o projeto.
Benefícios: Isso simplifica o processo de atualização de dependências, pois você precisa fazer a alteração em um só lugar. Além disso, evita a duplicação de dependências em diferentes partes do projeto.
Exemplo da main.dart de common_dependencies
export 'package:retrofit/retrofit.dart';
export 'package:retrofit_generator/retrofit_generator.dart';
export 'package:json_serializable/json_serializable.dart';
export 'package:dartz/dartz.dart';
export 'package:get_it/get_it.dart';
export 'package:mobx_codegen/mobx_codegen.dart';
export 'package:build_runner/build_runner.dart';
export 'package:image_picker/image_picker.dart';
export 'package:file_picker/file_picker.dart';
design_components:
Descrição: Aqui, você encontrará todos os componentes visuais reutilizáveis como botões, caixas de texto, paletas de cores e estilos de texto.
Benefícios: Isolar componentes visuais torna o projeto mais gerenciável e reutilizável. Isso também permite que designers e desenvolvedores front-end trabalhem de forma mais eficiente, pois os componentes podem ser facilmente importados e usados em diferentes partes do aplicativo.
Exemplo da main.dart de design_components, com o exemplo de quais arquivos são utilizados neste tipo de library:
export 'src/core/utils/custom_colors.dart';
export 'src/core/utils/fonts.dart';
export 'src/core/utils/helpers/assets_helper.dart';
export 'src/core/utils/helpers/image_picker_helper.dart';
export 'src/core/utils/helpers/masks_helper.dart';
export 'src/core/utils/helpers/scroll_listener_helper.dart';
export 'src/core/utils/helpers/select_pictures_sheet_helper.dart';
export 'src/core/components/components.dart';
A estrutura acima não só segue os princípios de programação modular, como também abstrai várias partes do sistema para torná-las independentes e reutilizáveis. Ela também facilita a integração contínua e entrega contínua (CI/CD), tornando mais fácil para os desenvolvedores colaborarem e manterem o projeto.
3. Por que Monorepo?
Reutilização de Código: Com uma estrutura monorepo, é mais fácil reutilizar código entre diferentes partes do projeto.
Gestão de Dependências: Ter todas as dependências em um local centralizado simplifica o versionamento e atualizações.
Integração e Teste: Um monorepo pode facilitar a integração contínua e a implementação de testes em diferentes módulos.
4. Criando uma Nova Library
Crie uma Nova Pasta:
mkdir nome_da_library
Inicialize um Novo Pacote Flutter:
flutter create --template=package nome_da_library
Adicione Dependências: Se a sua library precisa de dependências externas, adicione-as ao arquivo
pubspec.yaml
da library.
5. Utilizando Libraries no Projeto
Para utilizar uma library em outra parte do projeto:
Adicione a Dependência no
pubspec.yaml
:dependencies: nome_da_library: path: ../nome_da_library
Importe e Utilize: Em seu código, simplesmente importe e utilize as classes e funções da library:
import 'package:nome_da_library/nome_da_library.dart';
6. Recomendações Adicionais
Documentação Consistente: Cada library deve ter sua própria documentação, incluindo a finalidade da library, como utilizá-la e exemplos.
Testes: Assegure-se de incluir testes unitários e de integração em cada library. Isso garante que as funcionalidades fornecidas pela library sejam robustas e confiáveis.
Atualizações de Dependências: Ao atualizar uma dependência em
common_dependencies
, certifique-se de testar todas as libraries e o aplicativo principal para garantir a compatibilidade.
7. Conclusão
O uso de uma abordagem Monorepo em Flutter permite uma gestão mais eficaz e organizada do projeto. Ao separar a lógica de negócios, componentes visuais, dependências e a aplicação principal em diferentes libraries, você pode obter uma arquitetura modular que é fácil de manter, escalar e testar.
Embora a configuração inicial possa parecer mais complexa, os benefícios a longo prazo em termos de reutilização de código, gestão de dependências e colaboração entre equipes tornam o Monorepo uma escolha valiosa para projetos Flutter de grande escala.
Last updated