Standalone Components: o Angular sem NgModules

Standalone Components: o Angular sem NgModules

Robson Rabelo - 12 de julho de 2026 - 0 visualizações

O componente declara as próprias dependências e a burocracia dos NgModules vira opcional: bootstrap por função, lazy loading direto por rota e a migração quase mecânica.

Pergunte a quem tentou aprender Angular antes de 2023 onde travou, e a resposta tem nome: NgModule. Para mostrar um "olá mundo", era preciso entender declarations, imports, exports, providers e por que o componente "não é conhecido" apesar de estar ali do lado. Uma burocracia que existia por razões históricas do compilador, não por necessidade sua.

Standalone components removem essa camada: o componente declara as próprias dependências, e os NgModules viram opcionais. Desde o Angular 17, standalone é o padrão oficial para código novo (angular.dev).

O antes e o depois

// ANTES: o componente e a burocracia em arquivos separados
@Component({ selector: "app-card", templateUrl: "./card.html" })
export class CardComponent {}

@NgModule({
  declarations: [CardComponent],
  imports: [CommonModule, MatButtonModule],
  exports: [CardComponent],
})
export class CardModule {} // só para o de cima funcionar
// DEPOIS: o componente declara o que usa, e acabou
@Component({
  selector: "app-card",
  imports: [CurrencyPipe, MatButtonModule],
  templateUrl: "./card.html",
})
export class CardComponent {}

A mudança parece cosmética e não é: a dependência ficou local e explícita. Olhando o componente, você sabe exatamente do que ele precisa; movê-lo de lugar (ou de projeto) deixa de quebrar um módulo distante. O acoplamento invisível entre "quem declara" e "quem usa" morre.

O aplicativo sem módulos

O bootstrap troca o AppModule por uma chamada de função com providers:

// main.ts
bootstrapApplication(AppComponent, {
  providers: [
    provideRouter(rotas),
    provideHttpClient(),
    provideAnimations(),
  ],
});

E o lazy loading, que antes exigia um módulo por feature, agora aponta direto para componentes:

export const rotas: Routes = [
  {
    path: "relatorios",
    // carrega o código só quando a rota é visitada
    loadComponent: () =>
      import("./relatorios/relatorios.component").then((m) => m.RelatoriosComponent),
  },
  {
    path: "admin",
    loadChildren: () => import("./admin/admin.routes").then((m) => m.ADMIN_ROTAS),
  },
];

O carregamento preguiçoso ficou tão barato de declarar que a pergunta certa inverteu: em vez de "o que vale lazy?", "o que precisa mesmo estar no bundle inicial?". Para o LCP, essa inversão vale ouro.

Standalone: a dependência ficou local

Migrando um app existente (sem drama)

A migração é o raro caso de modernização quase mecânica:

  1. O schematic oficial faz o grosso: ng generate @angular/core:standalone converte componentes, remove módulos desnecessários e ajusta o bootstrap, em três passadas guiadas.
  2. Convivência total: standalone importa módulo antigo, módulo antigo importa standalone. Nada precisa migrar junto; é a substituição incremental de sempre.
  3. A ordem que funciona: componentes folha primeiro (os que nada declara além deles), depois as features, por último o shell e o bootstrap.

O que não migrar por reflexo: bibliotecas internas que expõem dezenas de componentes podem manter um NgModule de conveniência para os consumidores; o padrão standalone não proíbe, só desobriga.

O que isso conta sobre a direção do Angular

Standalone não veio sozinho: com Signals, control flow no template (@if, @for) e o caminho zoneless, o Angular está sistematicamente trocando cerimônia por clareza local: menos arquivos de cola, mais componente autocontido. Para times, o efeito prático é onboarding mais rápido e menos "arqueologia de módulo" na revisão de código.

Se o seu app ainda é 100% NgModule, a migração standalone costuma ser o primeiro passo que destrava as outras modernizações, e é um projeto bem definido, de risco baixo, do tipo que executamos no serviço de Desenvolvimento Web, Mobile e Desktop.

Quantos NgModules o seu app tem só para satisfazer o compilador? Rode o schematic num branch e conte o diff, ou descreva seu app para a IA da Rabelo Digital, aqui no canto da tela, e ela estima o esforço. Sem formulário, sem espera.


Leia também

Compartilhar:

Deixe um Comentário

Categorias

Posts Recentes