Monorepositório com Swift: organização de código para iniciantes
Quando você começa a desenvolver aplicativos em Swift para iOS ou macOS, mais cedo ou mais tarde surge a questão: como organizar o código para que ele não se transforme em um caos? Especialmente se você tiver vários projetos (por exemplo, um aplicativo iOS, uma extensão watchOS e um backend em Vapor). Uma das abordagens modernas é o monorepositório (monorepo). Neste artigo, vamos explorar o que é um monorepositório, por que ele é útil no desenvolvimento Swift e como organizá-lo na prática.
O que é um monorepositório e por que ele é necessário?
Um monorepositório (monorepo) é uma abordagem para gerenciamento de código onde todos os projetos, bibliotecas e módulos são armazenados em um único repositório (por exemplo, no Git). Ao contrário dos multirrepositórios, onde cada projeto vive em seu próprio repositório separado, o monorepositório une tudo em um só lugar.
Para desenvolvedores Swift, isso oferece várias vantagens:
- Versão única de dependências — você sabe exatamente qual versão de uma biblioteca está sendo usada em todos os projetos.
- Refatoração simplificada — uma alteração de API em uma biblioteca é imediatamente visível em todos os projetos dependentes.
- Configurações compartilhadas — um único SwiftLint, uma única configuração de CI/CD, regras de formatação únicas.
- Pesquisa fácil — tudo em um só lugar, sem necessidade de alternar entre repositórios.
No entanto, existem nuances: um monorepositório exige disciplina e uma estrutura adequada, caso contrário, pode se tornar uma "bagunça". Mas para iniciantes, é uma excelente maneira de aprender a organizar o código.
Estrutura de um monorepositório para projetos Swift
Suponha que você esteja criando um aplicativo para iOS com módulos compartilhados. Uma estrutura típica de monorepositório em Swift pode ser assim:
MyMonorepo/├── Apps/│ ├── iOSApp/ # Aplicativo iOS principal│ │ ├── Sources/│ │ ├── Resources/│ │ └── Package.swift│ └── macOSApp/ # Versão macOS│ ├── Sources/│ └── Package.swift├── Packages/│ ├── Core/ # Utilitários comuns (redes, logging)│ │ ├── Sources/│ │ └── Package.swift│ ├── UIComponents/ # Componentes de UI reutilizáveis│ │ ├── Sources/│ │ └── Package.swift│ └── Analytics/ # Módulo de análise│ ├── Sources/│ └── Package.swift├── Scripts/ # Scripts auxiliares├── .swiftlint.yml # Configuração única do linter├── Package.swift # Manifesto raiz (opcional)└── README.mdObserve que aqui é usado o Swift Package Manager (SPM) — a ferramenta padrão para gerenciamento de dependências em Swift. Cada módulo é um Swift Package separado que pode ser conectado aos aplicativos.
Como criar um monorepositório em Swift: guia passo a passo
Vamos criar um monorepositório simples com dois módulos e um aplicativo. Execute os seguintes passos no terminal:
Passo 1: Crie o diretório raiz e inicialize o Git
mkdir MyMonorepocd MyMonorepogit initPasso 2: Crie a estrutura de pastas
mkdir -p Apps/iOSApp/Sourcesmkdir -p Packages/Core/Sourcesmkdir -p Packages/UIComponents/SourcesPasso 3: Crie o Package.swift para o módulo Core
Crie o arquivo Packages/Core/Package.swift:
// swift-tools-version:5.9import PackageDescription
let package = Package( name: "Core", platforms: [ .iOS(.v16), .macOS(.v13) ], products: [ .library( name: "Core", targets: ["Core"]) ], targets: [ .target( name: "Core", path: "Sources") ])Passo 4: Escreva um código simples no módulo Core
Crie Packages/Core/Source