Confira as grandes novidades do Angular 16!

Andrew Rosário
5 min readMay 3, 2023

A equipe do Angular não está medindo esforços para trazer grandes novidades a cada versão lançada. Foi assim nas versões 14 e 15. Agora com a versão 16 não é diferente. O Angular progrediu muito em pouquíssimo tempo.

Como protocolo, uma nova versão do framework é lançada a cada 6 meses e dificilmente haviam mudanças significativas de uma versão pra outra. Isso não acontece mais, visto que as features desta nova versão vão mudar drasticamente a forma como escrevemos nossas aplicações.

Atualizando sua aplicação

Como muitos devem saber, é muito simples atualizar a versão da sua aplicação Angular utilizando o Angular CLI. Para atualizar para a versão 16 basta seguir o passo-a-passo no Guia de Atualização.

Agora que estamos com a aplicação atualizada, vamos conhecer as principais novidades apresentadas nesta versão.

Signals

Vamos iniciar com a feature mais importante. Mas o que diabos são esses Signals que vêm ganhando tanta atenção da comunidade?

Há alguns meses atrás a equipe do Angular anunciou um protótipo para adicionar uma abordagem primitiva para lidar com a reatividade dentro do framework. Esta abordagem se chama Signals e já é conhecida de outros frameworks como o SolidJS.

Como funciona a reatividade no Angular e por que mudar?

O Angular utiliza por baixo dos panos uma lib chamada zone.js. Ela tem o papel de interceptar todas as APIs assíncronas no navegador, utilizando-se de uma técnica chamada “Monkey Patching”. É o zone.js que age a partir da detecção de mudanças para saber quando atualizar o DOM.

A ideia de um Signal é não precisar mais utilizar o zone.js para detectar as mudanças, uma vez que ela se torna uma abordagem primitiva do framework.

Mas é claro que trocar uma abordagem por outra sem ter nenhum ganho não seria nada interessante. Signals ganharam muita visibilidade por conta da forma que são usados para propagar alterações em uma página. Eles criam uma espécie de “gráfico de reatividade” e são capazes de atualizar o DOM com precisão cirúrgica quando um Signal recebe um novo valor. Resultado: temos ganhos de performance.

Signals vão substituir o RxJS?

Quando o Angular anunciou a chegada dos Signals, muitas pessoas se perguntaram: eles estão deixando de lado o RxJS? A resposta é não. A verdade é que os dois se complementam. Podemos até transformar Signals em Observables e vice-versa.

O que podemos prever é que o uso de Observables terá uma diminuição nas aplicações Angular daqui pra frente. Muito do que fazíamos com o RxJS agora podemos fazer com Signals de uma forma mais simples.

Para fluxos síncronos e controle de estado, vale a pena usufruir de todo o poder de um Signal, já para fluxos assíncronos o RxJS ainda é a melhor opção.

É fato que a curva de aprendizado no RxJS é alta. Começar a pensar de forma declarativa e deixar de lado a forma imperativa leva tempo. Por mais que ele seja muito poderoso, acaba sendo bastante desafiador para novos desenvolvedores. Os Signals vieram também com esse intuito de fornecer uma jornada de aprendizado mais consolidada para essas pessoas.

Entenda neste post as principais características entre Signals e Observables.

DestroyRef Provider

A versão 16 introduziu um novo provider chamado DestroyRef que permite registrar callbacks de destroy para um de ciclo de vida específico.

@Component({ 
selector : 'app-root',
standalone : ​​true,
template : '',
})
class AppComponent {
constructor ( ) {
inject(DestroyRef).onDestroy(() => {
// executa algo quando o componente é destruído
})
}
}

A vantagem de se utilizar o DestroyRef perante o ngOnDestroy é que podemos criar uma lógica reutilizável que executa tarefas de limpeza necessárias.

Por exemplo, podemos criar um operador untilDestroyed que depende de DestroyRef. Veja este excelente exemplo trazido do artigo de Netanel Basal.

export function untilDestroyed() {
const subject = new Subject();
inject(DestroyRef).onDestroy(() => {
subject.next(true);
subject.complete();
});
return <T>() => takeUntil<T>(subject.asObservable());
}
@Directive({
selector: '[appFoo]',
standalone: true,
})
export class FooDirective {
private untilDestroyed = untilDestroyed();
ngOnInit() {
interval(1000)
.pipe(this.untilDestroyed())
.subscribe(console.log);
}
}

E melhor ainda, pensando numa maior facilidade para se desinscrever de Observables, a nova versão introduziu um novo operador chamado takeUntilDestroyed. Ele permite que você conclua um stream quando o contexto de um componente, diretiva ou pipe é destruído.

Required Inputs

Mais uma feature que era bastante aguardada pela comunidade! Ter a possibilidade de informar Inputs obrigatórios para um componente previne muitos bugs em tempo de desenvolvimento.

Antes para fazer essa validação era necessário adicionar um código a mais nos componentes. Agora caso o desenvolvedor esqueça de informar um Input obrigatório, imediatamente o Angular acusará um erro no momento da compilação.

Re-hidratação não destrutiva

Essa novidade vai para os desenvolvedores que atuam com Server Side Rendering.

Hidratação no desenvolvimento web refere-se ao processo de conversão de conteúdo HTML renderizado do lado do servidor em uma página web totalmente interativa e funcional no lado do cliente, anexando comportamento JavaScript e event listeners. Isso reduz o tempo de interação (TTI) e melhora o SEO e a acessibilidade.

Este recurso já está disponível há algum tempo em outros frameworks como o Next.js, mas no Angular não foi fácil de implementá-lo. Agora na versão 16, ao iniciar um projeto com o Angular Universal, já teremos a hidratação disponível para uso em uma aplicação SSR.

Dados de rotas via Input do componente

Outra feature que era aguardada há muito tempo. Antes da versão 16, a forma de capturar dados que uma rota provia (params, query params ou data) era injetando o ActivatedRoute. Agora todos esses dados podem ser recuperados simplesmente atribuindo um Input no componente. Basta nomear o Input da mesma forma que veio da rota.

Suporte para testes com Jest

O Angular adotou desde o início o framework de testes Jasmine em conjunto com o Test Runner Karma. Mas não é novidade para ninguém que este ambiente de testes as vezes pode ser bastante frustrante, principalmente em questões de performance e integração com CI.

Em contrapartida, o framework Jest vem ganhando cada vez mais popularidade na comunidade por seu ferramental e por ser mais leve também. Inclusive é a escolha padrão para projetos Angular utilizando o Nx.

Levando em conta todos esses feedbacks, a equipe do Angular disponibilizou na versão 16 o suporte oficial para o Jest como framework de testes. Vale destacar que este suporte ainda está em fase experimental, portanto ainda não deve ser utilizado em aplicações críticas.

Para selecionar o Jest basta alterar o seguinte código em angular.json:

{
"projects": {
"my-app": {
"architect": {
"test": {
"builder": "@angular-devkit/build-angular:jest",
"options": {
"tsConfig": "tsconfig.spec.json",
"polyfills": ["zone.js", "zone.js/testing"]
}
}
}
}
}
}

Conclusão

A versão 16 é sem dúvida uma das mais significativas que a equipe do Angular já lançou. Fica claro como o framework vem evoluindo e acompanhando o que há de mais moderno no mercado atual. Muitos outros recursos foram apresentados na versão, veja a lista completa neste link e no Blog oficial do Angular.

Podemos concluir que o Angular continua sendo uma escolha muito sólida para o desenvolvimento frontend. Com essas novidades podemos prever uma curva menor de aprendizado para novas pessoas, ao mesmo tempo que se obtém maiores ganhos de performance e experiência de desenvolvimento.

--

--

Andrew Rosário

Desenvolvedor Front-end, mentor e palestrante. Apaixonado por tecnologia e por compartilhar conhecimento.