Assim, saiu o angular 8, que inclui uma prévia do Ivy, suporte para profissionais de serviço, carregamento diferencial e alguns outros retoques finais.
Manfred Steyer explica as mudanças mais importantes na versão mais recente.
Como planejado, não houve surpresas: a atualização da estrutura e da CLI pode ser feita usando a atualização ng, e os novos recursos são uma boa adição ao lema "evolução em vez de revolução".
Neste artigo, o autor fala sobre os novos recursos mais importantes do Angular 8 e do Angular CLI 8. Os exemplos usados no artigo podem ser encontrados no
GitHub .
Sob o corte:
- Primeiro, olhe para Ivy
- Trabalhadores da Web
- Carga diferencial
- Módulos de carregamento preguiçoso
- Alterações críticas no ViewChild e no ContentChild
- Novos recursos ngUpgrade
Primeiro, olhe para Ivy
A próxima grande novidade que a comunidade Angular está esperando é Ivy, um novo compilador e também um novo mecanismo de renderização. Ivy pode gerar pacotes significativamente menores, compilação incremental e também é a base para futuras inovações no Angular.
Como muitas das partes básicas do Angular foram alteradas, a equipe do Angular prestou atenção especial à compatibilidade com versões anteriores: após a atualização para o Ivy, os aplicativos existentes devem funcionar da mesma maneira que antes. Na melhor das hipóteses, você terá pacotes muito menores. Isso não está desinteressado, já que mais de 600 aplicativos no Google são oficialmente baseados no Angular - há rumores de que o número real seja muito maior.
Com o Angular 8, uma versão preliminar do Ivy está disponível para teste. O objetivo desta versão é obter feedback rápido. Portanto, a equipe angular recomenda não usar Ivy no produto no momento, mas continuar usando o mecanismo de exibição clássico (Fig. 1)

Graças ao carregamento diferencial (como visto abaixo), os tamanhos dos pacotes podem ser otimizados agora.
De acordo com Brad Green, CTO da equipe Angular do Google, no ngconf 2019, a Ivy melhorará significativamente o tamanho dos pacotes no modo de compatibilidade combinado com o carregamento diferencial. Assim, os temerários já podem testar a futura API do Ivy. Esse modo, em particular, tem um grande potencial de otimização. A API ainda está marcada como privada. Observando suas classes e funções, você pode dizer: elas começam com um símbolo especial ɵ.
Se você já quiser experimentar o Ivy, poderá criar um novo projeto com a opção enable-ivy:
ng new ivy-project --enable-ivy
Essa chave informa à CLI para salvar a seguinte entrada na configuração tsconfig.app.json:
"angularCompilerOptions": { "enableIvy": true }
Esta entrada também pode ser adicionada manualmente após a atualização para a versão 8, para testar um aplicativo existente usando o Ivy.
Para executar o aplicativo no modo de depuração, é recomendável usar AOT:
ng serve --aot
Além disso, você deve prestar atenção ao tamanho do aplicativo criado usando o ng build. Com o angular 9, o Ivy deve ser ativado por padrão. Até então, a equipe Angular planeja continuar trabalhando para garantir a compatibilidade com versões mais antigas.
Trabalhadores da Web
O JavaScript é segmentado por definição. Por esse motivo, tarefas demoradas, como consulta de dados, geralmente são executadas de forma assíncrona. Escusado será dizer que isso não ajuda em cálculos complexos. Eles estão se tornando especialmente mais comuns com soluções abrangentes de JavaScript, por isso apoiamos profissionais da Web em quase todos os navegadores da Web. Esses scripts são iniciados pelo navegador em um encadeamento separado. A comunicação com o fluxo na guia do navegador é feita através de mensagens.
Embora os trabalhadores da Web não estejam relacionados ao Angular, eles devem ser levados em consideração na criação. O objetivo é fornecer um pacote para cada trabalhador da web. Esta tarefa foi concluída pela nova CLI.
Para demonstrar um novo recurso, mostrarei ao JavaScript a implementação do chamado "
problema das rainhas n ". A idéia é colocar uma rainha em uma fileira em um tabuleiro de xadrez, sem poder se ameaçar. a mesma linha, coluna ou diagonal não deve ser outra rainha.

O algoritmo para calcular todas as soluções possíveis em um tabuleiro de xadrez é considerado computacionalmente complexo. Embora os cálculos para um tabuleiro de xadrez regular de oito linhas e oito colunas sejam bastante rápidos, os computadores convencionais atingiram o limite com uma placa de 12 x 12. A solução para uma placa de 27 x 27 é o recorde atual. Para esta tarefa, foram utilizados supercomputadores russos.
Para converter esse cálculo em segundo plano, primeiro precisamos criar um trabalhador da Web usando a CLI:
ng generate worker n-queens
Esta instrução cria um arquivo não apenas para o funcionário, mas também para os arquivos de configuração necessários para o processo de construção e as entradas nos arquivos existentes. Se a mesma pasta contiver um componente com o mesmo nome e uma extensão de arquivo .component.ts comum, a CLI também adicionará código para interagir com o trabalhador da Web.
O próprio trabalhador consiste em um ouvinte para o evento:
import nQueens from './n-queens'; addEventListener('message', ({ data }) => { const result = nQueens(data.count); postMessage(result, undefined); });
O evento é executado quando o thread principal envia uma mensagem para o trabalhador. O parâmetro contém informações enviadas do fluxo principal. Nesse caso, é limitado pela propriedade count, que define o tamanho do tabuleiro de xadrez. Após avaliar a função nQueens, que é omitida aqui, eventListener envia o resultado de volta ao encadeamento principal por meio de postMessage. Assim, o navegador dispara um evento de mensagem.
A classe Worker é usada no componente using para interagir com o script worker:
const count = parseInt(this.count, 10); const worker = new Worker('../logic/n-queens.worker', { type: 'module'
O componente envia uma mensagem com o tamanho desejado do tabuleiro de xadrez ao trabalhador via postMessage e, assim, inicia o cálculo lá. Ele recebe o resultado através do evento da mensagem.
No futuro, a CLI cuidará da montagem correta dos scripts de trabalho. O compilador TypeScript os reconhece no final do arquivo .worker.ts, registrado no tsconfig.worker.json criado pelo comando
ng generate worker . Para garantir que a CLI não afete esses arquivos novamente ao criar o aplicativo principal, o
ng generate worker coloca o mesmo modelo de arquivo na seção excluir do tsconfig.app.json.
A implementação completa está no projeto, com exemplos do autor. Para comparação, um exemplo da tarefa N queens pode ser resolvido no encadeamento principal e no web worker. Ao tentar resolver um problema para um tabuleiro de xadrez 12 x 12, por exemplo, você verá que a interface do usuário trava no primeiro caso, enquanto o cálculo em segundo plano com o trabalhador da Web não reduz o desempenho.
Carga diferencial
Até agora, costumava-se compilar aplicativos no bom e velho ES 5, já que esta versão do "JavaScript of our father" funciona em quase todos os lugares. Isso significa que o IE11 e o rastreador da Web do Google podem executar esse código.
No entanto, o novo ES 2015 e suas versões subsequentes são mais eficientes: permitem criar pacotes mais compactos e o navegador também pode interpretá-los com mais eficiência. Como anteriormente era costume reverter para o ES 5 como o denominador menos comum, os navegadores modernos, infelizmente, não podiam tirar proveito da nova versão do idioma.
Agora acabou: a partir da versão 8, a CLI possui um recurso chamado carregamento diferencial. A idéia é fornecer dois grupos de pacotes: um baseado no ECMAScript 5 e projetado para navegadores mais antigos, o outro baseado em uma nova versão do ECMAScript, como o ECMAScript 2015, e fornece aos navegadores modernos os benefícios mencionados anteriormente.
Você não precisa fazer muito trabalho para ativar o carregamento diferencial: tudo o que é necessário é definir os limites superior e inferior das versões suportadas do ECMAScript. O limite superior é indicado no tsconfig.json da seguinte maneira:
"target": "es2015"
O limite inferior é definido no arquivo da lista de navegadores. Este arquivo inclui navegadores que serão suportados de acordo com certos critérios, como participação de mercado, por exemplo. Eles podem ser salvos, por exemplo, no arquivo da lista de navegadores, que a CLI cria na raiz do projeto ao criar um novo projeto:
> 0.5%
last 2 versions
Firefox ESR
not dead
IE 9-11
Nesse caso, a lista de navegadores inclui navegadores ES 5 com uma entrada do IE 9-11. Assim, a CLI define o limite inferior como esta versão. Quando a CLI recebe o comando ng build, o processo de construção será executado nas duas versões:

A desvantagem desse processo é esta: o tempo necessário para a montagem dobra.
Os navegadores agora podem decidir qual versão dos pacotes baixar. Para fazer isso, eles recebem links para scripts no complemento index.html: aqueles que apontam para os pacotes do ECMAScript 5 recebem a adição de um nomodule. Portanto, os navegadores com suporte ao ECMAScript e, portanto, o suporte ao ECMAScript 2015+ não ignoram esse script. Por outro lado, os pacotes ECMAScript 2015+ são implementados pela CLI com o tipo = ”module”. Assim, navegadores mais antigos irão ignorar estes scripts:
<script src="main-es2015.js" type="module"></script> <script src="main-es5.js" nomodule></script>
Ao contrário do ng build, o restante dos comandos da CLI usa apenas (!) O limite superior do suporte do ES. No nosso caso, é o ECMAScript 2015. Isso acontece, inclusive por razões de eficiência: durante a depuração e o teste, os desenvolvedores geralmente desejam ver o resultado o mais rápido possível, sem aguardar a segunda compilação.
Módulos de carregamento preguiçoso
Desde os primeiros dias, o roteador Angular suporta carregamento lento. Até agora, isso foi alcançado com a definição mágica de um módulo carregável:
{ path: 'lazy', loadChildren: () => './lazy/lazy.module#LayzModule' }
O valor antes de # descreve o caminho que leva ao arquivo de implementação do módulo; o valor depois significa a classe contida nele. Esse estilo de descrição funciona no Angular 8, mas foi preterido em relação às importações dinâmicas do ECMAScript:
{ path: 'lazy', loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule) }
A nova opção de registro ainda contém o nome do arquivo como um valor mágico. No entanto, como as importações são suportadas por muitos IDEs, valores inválidos retornarão imediatamente um erro.
Alterações críticas no ViewChild e no ContentChild
Existem mudanças críticas no uso do ViewChild e do ContentChild, que, infelizmente, no passado nem sempre funcionavam de forma previsível. Se nas versões anteriores eles eram usados por um componente para consultar elementos que não estão dentro de uma diretiva estrutural, como ngIf ou ngFor, o resultado da consulta já estava disponível no ngOnInit. Caso contrário, não poderíamos acessá-los antes do ngAfterViewInit (ou ngAfterContentInit for ContentChild). Para elementos que foram carregados no DOM posteriormente devido à ligação de dados, o código do programa deve ter ngAfterViewChecked ou, consequentemente, ngAfterContentChecked.
Como esse comportamento foi confuso, o componente agora deve indicar quando a resolução deve ocorrer:
@ViewChild('info', { static: false }) paragraph: ElementRef;
Se o sinalizador estático for verdadeiro, o Angular tentará encontrar os elementos quando o componente for inicializado. Isso só funciona se eles não estiverem na diretiva estrutural. Ao usar static: false, a resolução é executada após a inicialização ou atualização da exibição.
ng update tentará inserir automaticamente o valor correto; se isso não for possível, ele adicionará um comentário com TODO.
Essa alteração não afetará as consultas com os decoradores ViewChildren e ContentChildren. Eles sempre tiveram um comportamento dinâmico, em novos termos no sentido de estático: falso.
Novos recursos ngUpgrade
Até agora, um dos problemas do AngularJS 1.X e do Angular misturados ao ngUpgrade foi o fato de os roteadores de ambas as estruturas competirem devido à URL. Isso levou a difícil explicar os efeitos colaterais. Para evitar isso, foi adicionada a capacidade de usar um único serviço de localização de URL nas duas versões.
Para fazer isso, a equipe Angular expandiu os recursos dos serviços de localização Angular e, portanto, forneceu uma substituição para $ location no AngularJS.
Por esse motivo, um novo método onUrlChange foi adicionado ao serviço de localização para rastrear alterações de URL:
export class AppComponent { constructor(loc: Location, pLoc: PlatformLocation) { loc.onUrlChange((url) => console.debug('url change', url)); console.debug('hostname: ', pLoc.hostname); } }
O serviço PlatformLocation oferece acesso adicional a partes específicas da URL. Uma descrição detalhada de como a substituição da localização $ baseada nela é usada para integrar melhor as estruturas pode ser encontrada
aqui . Além disso, agora você pode encontrar a solução de carregamento lento do AngularJS, que se baseia na importação dinâmica mencionada acima do ECMAScript.
Conclusão
Mais uma vez, a equipe do Angular manteve sua palavra: a transição para a nova versão do Angular é simples e não inclui grandes mudanças. Pelo contrário, alguns cantos foram suavizados, tornando o trabalho com a estrutura de SPA do Google ainda mais confortável. O carregamento diferencial oferece oportunidades para otimização adicional dos tamanhos dos pacotes se navegadores mais antigos não forem suportados ou suportados por pacotes separados. O suporte ao trabalhador da Web mostra que as tarefas intensivas em computação encontram o caminho para o processamento no navegador. Agora, os entusiastas podem dar os primeiros passos com Ivy.
PS: Esta é a minha primeira tradução, portanto, observe comentários, sugestões e erros nos comentários.