Um monólito modular envia um único binário instalável com módulos de funcionalidade ativados por flags e configuração. Multi-App em repositórios constrói listagens de loja separadas - diferentes IDs de pacote, ícones e, muitas vezes, trens de lançamento independentes. Escolha com base na independência de lançamento, não na preferência da equipe.
# Mesmo repositório - diferentes aplicativos instaláveis via perfis EASAPP_VARIANT=consumer eas build --profile production-consumer --platform iosAPP_VARIANT=business eas build --profile production-business --platform ios
Quando usar isso:
O produto solicita um "aplicativo de negócios" ao lado do consumidor - decida se é uma flag ou uma listagem na loja.
Clientes white-label precisam de IDs de pacote personalizados, mas compartilham 90% do código.
A conformidade exige o isolamento de ferramentas administrativas de binários voltados para o consumidor.
Gerentes de lançamento desejam um ou dois registros no App Store Connect.
# Layout do repositório multi-app (quando as listagens divergem totalmente)apps/├── consumer-mobile/ # slug: shop-consumer└── business-mobile/ # slug: shop-businesspackages/├── features/ # módulos de funcionalidade compartilhados└── ui/
O que isso demonstra:
Monólito modular alterna a aba b2bPortal via extra.featureFlags - uma base de código, dois perfis EAS.
APP_VARIANT altera o ID do pacote e o nome de exibição - os usuários instalam dois aplicativos de um único repositório.
O layout Multi-App separa apps/consumer-mobile e apps/business-mobile quando CI, ícones e configuração nativa divergem muito.
Flags de funcionalidade ocultam a interface do usuário - elas não removem código morto do binário, a menos que sejam combinadas com a remoção em tempo de compilação.
// Falha fechada quando o módulo necessário está desativadoimport { getFeatureFlags } from "@/shared/config/featureFlags";export function B2BPortalScreen() { if (!getFeatureFlags().b2bPortal) { return null; // ou redirecionar - a rota também deve ser desregistrada } // ...}
Prefira excluir rotas do navegador em vez de renderizar telas vazias.
Flags de funcionalidade sem limites de módulo - O B2B desabilitado ainda se conecta se as importações de features/b2b vazarem. Correção: Isole features/b2b; use lint-import para impedir que aplicativos apenas para consumidores o importem.
Um slug, dois IDs de pacote - O painel Expo e os canais OTA se confundem. Correção: Canais EAS Update separados por APP_VARIANT.
Flags de tempo de execução para conformidade - O código administrativo ainda está no bundle JS. Correção: Multi-App ou exclusão em tempo de compilação para SKUs regulamentadas.
Divisão prematura para multi-app - Dois aplicativos, 99% de código compartilhado, custo de CI dobrado. Correção: Comece com monólito + variantes; extraia apps/ quando a configuração nativa divergir.
URLs de API codificadas para cada aplicativo - Lógica de ambiente duplicada. Correção: Centralize getAppConfig() com chave appVariant.
Expo Go não pode testar variantes realisticamente - IDs de pacote e ícones precisam de compilações de desenvolvimento. Correção: Perfil de desenvolvimento EAS por variante.
if (flags.x) gigante em cada tela - Ramificação intratável. Correção: Registre rotas e navegadores a partir de um único useAppRoutes() / manifesto de módulo.
O que é um monólito modular em dispositivos móveis?
Um único binário de aplicativo instalável contendo múltiplos módulos de funcionalidade. Os módulos são delimitados no código (features/b2b) e habilitados por configuração ou flags - não microsserviços separados.
Quando um binário com flags é suficiente?
Quando os produtos compartilham navegação, plugins nativos e cadência de lançamento - apenas algumas abas ou fluxos diferem (portal B2B, recursos beta, branding do tenant).
Quando preciso de aplicativos separados no repositório?
Quando os IDs de pacote, contas de loja, direitos nativos ou cronogramas de lançamento são genuinamente independentes - não apenas temas diferentes.
As flags de funcionalidade removem código do bundle?
Flags de tempo de execução ocultam a interface do usuário; elas não fazem tree-shake de módulos nativos. Use variantes em tempo de compilação ou aplicativos separados para excluir SDKs regulamentados.
Como o Expo Updates funciona com variantes?
Atribua um canal por variante (production-consumer, production-business). Publicar no canal errado atualiza a listagem errada.
O monólito modular pode suportar white-label?
Sim - TENANT env em app.config.ts por perfil EAS. packages/features compartilhados contêm o código; os ativos do tenant residem no env específico do perfil ou em assets/tenants/<nome>/.
APP_VARIANT vs. flags de funcionalidade EXPO_PUBLIC?
APP_VARIANT geralmente direciona a identidade (nome, ID do pacote) em tempo de compilação. Flags EXPO_PUBLIC_* são adequadas para experimentos em tempo de execução incorporados em JS - ambos podem coexistir.
Como ocultar rotas do Expo Router quando uma flag está desativada?
Registre condicionalmente entradas Tabs.Screen / Stack.Screen de um manifesto de rotas - não confie que os usuários nunca farão deep-link para caminhos desativados.
Multi-App é o mesmo que Monorepo?
Não. Monorepo é o layout do repositório. Multi-App significa múltiplos aplicativos Expo (apps/a, apps/b). Um monorepo pode hospedar um aplicativo (monólito modular) ou muitos.
E quanto ao Android applicationId vs iOS bundleIdentifier?
Ambos se ramificam de app.config.ts por variante. Mantenha-os sincronizados com APP_VARIANT - IDs incompatíveis quebram deep links e credenciais push.
Posso mesclar os aplicativos consumidor e de negócios mais tarde?
Mais fácil do que dividir. Migre módulos apenas de negócios para trás de flags, unifique a estratégia de ID de pacote deliberadamente - as listagens na loja podem exigir reinstalação pelo usuário.
Como isso se relaciona com os perfis de compilação EAS?
Cada perfil define env (APP_VARIANT, TENANT, flags). Perfis são o mecanismo de entrega para variantes de monólito e destinos multi-app.
B2B e consumidor devem compartilhar análises?
Espaços de nomes de eventos arquitetonicamente separados por appVariant. Multi-App pode usar projetos de análise diferentes - planeje antes de mesclar dashboards.
Monólito modular vs. serviço de flags de funcionalidade?
Flags locais controlam módulos e navegação em tempo de compilação. Serviços de flags remotos controlam experimentos - use ambos: limites de módulo localmente, remoto para A/B.