Components standalone fornecem uma maneira simplificada de construir aplicações Angular. Components, directives e pipes standalone visam simplificar a experiência de autoria reduzindo a necessidade de NgModules. Aplicações existentes podem opcionalmente e incrementalmente adotar o novo estilo standalone sem nenhuma breaking change.
Este schematic ajuda a transformar components, directives e pipes em projetos existentes para se tornarem standalone. O schematic visa transformar o máximo de código possível automaticamente, mas pode exigir algumas correções manuais pelo autor do projeto.
Execute o schematic usando o seguinte comando:
ng generate @angular/core:standalone
Antes de atualizar
Antes de usar o schematic, certifique-se de que o projeto:
- Está usando Angular 15.2.0 ou posterior.
- Compila sem nenhum erro de compilação.
- Está em um branch Git limpo e todo o trabalho está salvo.
Opções do schematic
| Opção | Detalhes |
|---|---|
mode |
A transformação a realizar. Veja Modos de migração abaixo para detalhes sobre as opções disponíveis. |
path |
O caminho para migrar, relativo à raiz do projeto. Você pode usar esta opção para migrar seções do seu projeto incrementalmente. |
Etapas de migração
O processo de migração é composto de três etapas. Você terá que executá-lo várias vezes e verificar manualmente se o projeto compila e se comporta conforme esperado.
NOTE: Embora o schematic possa atualizar automaticamente a maioria do código, alguns casos extremos requerem intervenção do desenvolvedor. Você deve planejar aplicar correções manuais após cada etapa da migração. Adicionalmente, o novo código gerado pelo schematic pode não corresponder às regras de formatação do seu código.
Execute a migração na ordem listada abaixo, verificando se seu código compila e executa entre cada etapa:
- Execute
ng g @angular/core:standalonee selecione "Convert all components, directives and pipes to standalone" - Execute
ng g @angular/core:standalonee selecione "Remove unnecessary NgModule classes" - Execute
ng g @angular/core:standalonee selecione "Bootstrap the project using standalone APIs" - Execute quaisquer verificações de linting e formatação, corrija quaisquer falhas e faça commit do resultado
Após a migração
Parabéns, sua aplicação foi convertida para standalone 🎉. Aqui estão algumas etapas opcionais de acompanhamento que você pode querer realizar agora:
- Encontre e remova quaisquer declarações
NgModulerestantes: como a etapa "Remove unnecessary NgModules" não pode remover todos os módulos automaticamente, você pode ter que remover as declarações restantes manualmente. - Execute os testes unitários do projeto e corrija quaisquer falhas.
- Execute quaisquer formatadores de código, se o projeto usa formatação automática.
- Execute quaisquer linters em seu projeto e corrija novos avisos. Alguns linters suportam uma flag
--fixque pode resolver alguns de seus avisos automaticamente.
Modos de migração
A migração tem os seguintes modos:
- Converter declarações para standalone.
- Remover NgModules desnecessários.
- Mudar para API de bootstrap standalone. Você deve executar essas migrações na ordem dada.
Converter declarações para standalone
Neste modo, a migração converte todos os components, directives e pipes para standalone removendo standalone: false e adicionando dependências ao seu array imports.
HELPFUL: O schematic ignora NgModules que fazem bootstrap de um component durante esta etapa porque eles são provavelmente módulos raiz usados por bootstrapModule em vez do bootstrapApplication compatível com standalone. O schematic converte essas declarações automaticamente como parte da etapa "Mudar para API de bootstrap standalone".
Antes:
// shared.module.ts@NgModule({ imports: [CommonModule], declarations: [GreeterComponent], exports: [GreeterComponent]})export class SharedModule {}
// greeter.component.ts@Component({ selector: 'greeter', template: '<div *ngIf="showGreeting">Hello</div>', standalone: false,})export class GreeterComponent { showGreeting = true;}
Depois:
// shared.module.ts@NgModule({ imports: [CommonModule, GreeterComponent], exports: [GreeterComponent]})export class SharedModule {}
// greeter.component.ts@Component({ selector: 'greeter', template: '<div *ngIf="showGreeting">Hello</div>', imports: [NgIf]})export class GreeterComponent { showGreeting = true;}
Remover NgModules desnecessários
Após converter todas as declarações para standalone, muitos NgModules podem ser removidos com segurança. Esta etapa deleta tais declarações de módulo e o máximo de referências correspondentes possível. Se a migração não puder deletar uma referência automaticamente, ela deixa o seguinte comentário TODO para que você possa deletar o NgModule manualmente:
/* TODO(standalone-migration): clean up removed NgModule reference manually */
A migração considera um módulo seguro para remover se esse módulo:
- Não tem
declarations. - Não tem
providers. - Não tem components de
bootstrap. - Não tem
importsque referenciam um símboloModuleWithProvidersou um módulo que não pode ser removido. - Não tem membros de classe. Construtores vazios são ignorados.
Antes:
// importer.module.ts@NgModule({ imports: [FooComponent, BarPipe], exports: [FooComponent, BarPipe]})export class ImporterModule {}
Depois:
// importer.module.ts// Não existe!
Mudar para API de bootstrap standalone
Esta etapa converte quaisquer usos de bootstrapModule para a nova API bootstrapApplication baseada em standalone. Ela também remove standalone: false do component raiz e deleta o NgModule raiz. Se o módulo raiz tiver quaisquer providers ou imports, a migração tenta copiar o máximo possível dessa configuração para a nova chamada de bootstrap.
Antes:
// ./app/app.module.tsimport { NgModule } from '@angular/core';import { AppComponent } from './app.component';@NgModule({ declarations: [AppComponent], bootstrap: [AppComponent]})export class AppModule {}
// ./app/app.component.ts@Component({ selector: 'app', template: 'hello', standalone: false,})export class AppComponent {}
// ./main.tsimport { platformBrowser } from '@angular/platform-browser';import { AppModule } from './app/app.module';platformBrowser().bootstrapModule(AppModule).catch(e => console.error(e));
Depois:
// ./app/app.module.ts// Não existe!
// ./app/app.component.ts@Component({ selector: 'app', template: 'hello'})export class AppComponent {}
// ./main.tsimport { bootstrapApplication } from '@angular/platform-browser';import { AppComponent } from './app/app.component';bootstrapApplication(AppComponent).catch(e => console.error(e));
Problemas comuns
Alguns problemas comuns que podem impedir que o schematic funcione corretamente incluem:
- Erros de compilação - se o projeto tem erros de compilação, o Angular não pode analisar e migrá-lo corretamente.
- Arquivos não incluídos em um tsconfig - o schematic determina quais arquivos migrar analisando os arquivos
tsconfig.jsondo seu projeto. O schematic exclui quaisquer arquivos não capturados por um tsconfig. - Código que não pode ser analisado estaticamente - o schematic usa análise estática para entender seu código e determinar onde fazer mudanças. A migração pode pular quaisquer classes com metadata que não podem ser analisados estaticamente em tempo de build.
Limitações
Devido ao tamanho e complexidade da migração, existem alguns casos que o schematic não pode lidar:
- Como testes unitários não são compilados ahead-of-time (AoT),
importsadicionados a components em testes unitários podem não estar totalmente corretos. - O schematic depende de chamadas diretas para APIs do Angular. O schematic não pode reconhecer wrappers customizados em torno de APIs do Angular. Por exemplo, se você definir uma função customizada
customConfigureTestModuleque envolveTestBed.configureTestingModule, components que ela declara podem não ser reconhecidos.