Como criar modelos angulares melhores com o Pug
Publicados: 2022-03-10Como desenvolvedor, aprecio como os aplicativos Angular são estruturados e as muitas opções que o Angular CLI disponibiliza para configurá-los. Os componentes fornecem um meio incrível para estruturar exibições, facilitar a reutilização de código, interpolação, vinculação de dados e outras lógicas de negócios para exibições.
A Angular CLI suporta várias opções de pré-processador CSS integradas para estilo de componentes como Sass/SCSS, LESS e Stylus. No entanto, quando se trata de modelos, apenas duas opções estão disponíveis: HTML e SVG. Isso apesar de existirem muitas opções mais eficientes, como Pug, Slim, HAML, entre outras.
Neste artigo, abordarei como você - como desenvolvedor Angular - pode usar o Pug para escrever modelos melhores com mais eficiência. Você aprenderá como instalar o Pug em seus aplicativos Angular e fazer a transição de aplicativos existentes que usam HTML para usar o Pug.
Gerenciando pontos de interrupção de imagem
Um recurso Angular integrado chamado BreakPoint Observer nos oferece uma interface poderosa para lidar com imagens responsivas. Leia mais sobre um serviço que nos permite servir, transformar e gerenciar imagens na nuvem. Leia um artigo relacionado →
Pug (anteriormente conhecido como Jade) é um mecanismo de modelo. Isso significa que é uma ferramenta que gera documentos a partir de templates que integram alguns dados especificados. Nesse caso, o Pug é usado para escrever modelos que são compilados em funções que recebem dados e renderizam documentos HTML.
Além de fornecer uma maneira mais simplificada de escrever modelos , ele oferece vários recursos valiosos que vão além da escrita de modelos, como mixins que facilitam a reutilização de código, permitem a incorporação de código JavaScript, fornecem iteradores, condicionais e assim por diante.
Embora o HTML seja universalmente usado por muitos e funcione adequadamente em modelos, ele não é DRY e pode ficar muito difícil de ler, escrever e manter, especialmente com modelos de componentes maiores. É aí que entra o Pug. Com o Pug, seus modelos se tornam mais simples de escrever e ler e você pode estender a funcionalidade do seu modelo como um bônus adicional . No restante deste artigo, mostrarei como usar o Pug em seus modelos de componentes Angular.
Por que você deve usar o Pug
HTML é fundamentalmente repetitivo. Para a maioria dos elementos, você precisa ter uma tag de abertura e fechamento que não seja DRY. Você não apenas precisa escrever mais com HTML, mas também ler mais. Com o Pug, não há colchetes angulares de abertura e fechamento e nem tags de fechamento. Você está, portanto, escrevendo e lendo muito menos código.
Por exemplo, aqui está uma tabela HTML:
<table> <thead> <tr> <th>Country</th> <th>Capital</th> <th>Population</th> <th>Currency</th> </tr> </thead> <tbody> <tr> <td>Canada</td> <td>Ottawa</td> <td>37.59 million</td> <td>Canadian Dollar</td> </tr> <tr> <td>South Africa</td> <td>Cape Town, Pretoria, Bloemfontein</td> <td>57.78 million</td> <td>South African Rand</td> </tr> <tr> <td>United Kingdom</td> <td>London</td> <td>66.65 million</td> <td>Pound Sterling</td> </tr> </tbody> </table>
É assim que essa mesma tabela se parece no Pug:
table thead tr th Country th Capital(s) th Population th Currency tbody tr td Canada td Ottawa td 37.59 million td Canadian Dollar tr td South Africa td Cape Town, Pretoria, Bloemfontein td 57.78 million td South African Rand tr td United Kingdom td London td 66.65 million td Pound Sterling
Comparando as duas versões da tabela, o Pug parece muito mais limpo que o HTML e tem melhor legibilidade do código. Embora insignificante neste pequeno exemplo, você escreve sete linhas a menos na tabela Pug do que na tabela HTML. À medida que você cria mais modelos ao longo do tempo para um projeto, acaba escrevendo cumulativamente menos código com o Pug .
Além da funcionalidade fornecida pela linguagem de templates Angular, o Pug estende o que você pode alcançar em seus templates. Com recursos (como mixins, interpolação de texto e atributo, condicionais, iteradores e assim por diante), você pode usar o Pug para resolver problemas de forma mais simples, em contraste com escrever componentes separados inteiros ou importar dependências e configurar diretivas para atender a um requisito.
Algumas características do pug
O Pug oferece uma ampla variedade de recursos, mas quais recursos você pode usar dependem de como você integra o Pug em seu projeto. Aqui estão alguns recursos que você pode achar úteis.
- Adicionando arquivos Pug externos a um modelo usando
include
.
Digamos, por exemplo, que você gostaria de ter um template mais sucinto, mas não sente a necessidade de criar componentes adicionais. Você pode retirar seções de um modelo e colocá-las em modelos parciais e, em seguida, incluí-las de volta no modelo original.
Por exemplo, neste componente de página inicial, as seções 'Sobre' e 'Serviços' estão em arquivos externos e estão incluídas no componente de página inicial.//- home.component.pug h1 Leone and Sons h2 Photography Studio include partials/about.partial.pug include partials/services.partial.pug
//- about.partial.pug h2 About our business p Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
//- services.partial.pug h2 Services we offer P Our services include: ul li Headshots li Corporate Event Photography
Exemplo de renderização HTML de modelos parciais incluídos (visualização grande) - Reutilizando blocos de código usando mixins .
Por exemplo, digamos que você queira reutilizar um bloco de código para criar alguns botões. Você reutilizaria esse bloco de código usando um mixin.mixin menu-button(text, action) button.btn.btn-sm.m-1('(click)'=action)&attributes(attributes)= text +menu-button('Save', 'saveItem()')(class="btn-outline-success") +menu-button('Update', 'updateItem()')(class="btn-outline-primary") +menu-button('Delete', 'deleteItem()')(class="btn-outline-danger")
Renderização HTML de exemplo de mixagem de botões de menu (visualização grande) - As condicionais facilitam a exibição de blocos de código e comentários com base no cumprimento de uma condição ou não.
- var day = (new Date()).getDay() if day == 0 p We're closed on Sundays else if day == 6 p We're open from 9AM to 1PM else p We're open from 9AM to 5PM
Exemplo de renderização HTML de condicionais (visualização grande) - Iteradores como
each
ewhile
fornecem funcionalidade de iteração .ul each item in ['Eggs', 'Milk', 'Cheese'] li= item ul while n < 5 li= n++ + ' bottles of milk on the wall'
(Visualização grande) Exemplo de renderizações HTML de iteradores (visualização grande) - JavaScript embutido pode ser escrito em templates Pug conforme demonstrado nos exemplos acima.
- A interpolação é possível e se estende a tags e atributos.
- var name = 'Charles' p Hi! I'm #{name}. p I'm a #[strong web developer]. a(href='https://about.me/${name}') Get to Know Me
Renderização HTML de exemplo de interpolação (visualização grande) - Os filtros permitem o uso de outras linguagens em templates Pug .
Por exemplo, você pode usar Markdown em seus modelos Pug após instalar um módulo JSTransformer Markdown.:markdown-it # Charles the Web Developer  ## About Charles has been a web developer for 20 years at **Charles and Co Consulting.**
Renderização HTML do exemplo de filtro (visualização grande)
Essas são apenas algumas das funcionalidades oferecidas pelo Pug. Você pode encontrar uma lista mais ampla de recursos na documentação do Pug.

Como usar o Pug em um aplicativo angular
Para aplicativos novos e pré-existentes usando Angular CLI 6 e superior, você precisará instalar ng-cli-pug-loader
. É um carregador Angular CLI para modelos Pug.
Para novos componentes e projetos
- Instale
ng-cli-pug-loader
.ng add ng-cli-pug-loader
- Gere seu componente de acordo com suas preferências.
Por exemplo, digamos que estamos gerando um componente de página inicial:ng gc home --style css -m app
- Altere a extensão do arquivo HTML,
.html
para uma extensão Pug,.pug
. Como o arquivo inicial gerado contém HTML, você pode optar por excluir seu conteúdo e começar de novo com o Pug. No entanto, o HTML ainda pode funcionar em modelos Pug para que você possa deixá-lo como está. - Altere a extensão do modelo para
.pug
no decorador de componentes.@Component({ selector: 'app-component', templateUrl: './home.component.pug', styles: ['./home.component.css'] })
Para componentes e projetos existentes
- Instale
ng-cli-pug-loader
.ng add ng-cli-pug-loader
- Instale a ferramenta CLI html2pug. Esta ferramenta irá ajudá-lo a converter seus templates HTML para Pug.
npm install -g html2pug
- Para converter um arquivo HTML para Pug, execute:
html2pug -f -c < [HTML file path] > [Pug file path]
-f
para indicar aohtml2pug
que ele não deve envolver os templates que gera em tagshtml
ebody
. O sinalizador-c
permitehtml2pug
saber que os atributos dos elementos devem ser separados por vírgulas durante a conversão. Vou cobrir por que isso é importante abaixo. - Altere a extensão do modelo para
.pug
no decorador de componentes conforme descrito na seção Para novos componentes e projetos . - Execute o servidor para verificar se não há problemas com a renderização do modelo Pug.
Se houver problemas, use o modelo HTML como referência para descobrir o que pode ter causado o problema. Isso às vezes pode ser um problema de recuo ou um atributo não citado, embora raro. Quando estiver satisfeito com a renderização do modelo Pug, exclua o arquivo HTML.
Coisas a considerar ao migrar de HTML para modelos Pug
Você não poderá usar modelos Pug embutidos com ng-cli-pug-loader
. Isso renderiza apenas arquivos Pug e não renderiza modelos embutidos definidos em decoradores de componentes. Portanto, todos os modelos existentes precisam ser arquivos externos. Se você tiver algum modelo HTML embutido, crie arquivos HTML externos para eles e converta-os para Pug usando html2pug
.
Uma vez convertido, você pode precisar corrigir modelos que usam diretivas de associação e atributo. ng-cli-pug-loader
requer que os nomes de atributos vinculados em Angular sejam colocados entre aspas simples ou duplas ou separados por vírgulas. A maneira mais fácil de fazer isso seria usar o sinalizador -c
com html2pug
. No entanto, isso apenas corrige os problemas com elementos que possuem vários atributos. Para elementos com atributos únicos, use aspas.
Muitas das configurações descritas aqui podem ser automatizadas usando um executor de tarefas ou um script ou um esquema Angular personalizado para conversões em grande escala, se você optar por criar um. Se você tiver alguns modelos e quiser fazer uma conversão incremental, seria melhor converter apenas um arquivo de cada vez.
Sintaxe de linguagem de modelo angular em modelos de Pug
Na maioria das vezes, a sintaxe da linguagem de modelo Angular permanece inalterada em um modelo Pug, no entanto, quando se trata de vinculação e algumas diretivas (como descrito acima), você precisa usar aspas e vírgulas desde ()
, []
e [()]
interferem na compilação de templates Pug. Aqui estão alguns exemplos:
//- [src], an attribute binding and [style.border], a style binding are separated using a comma. Use this approach when you have multiple attributes for the element, where one or more is using binding. img([src]='itemImageUrl', [style.border]='imageBorder') //- (click), an event binding needs to be enclosed in either single or double quotes. Use this approach for elements with just one attribute. button('(click)'='onSave($event)') Save
Diretivas de atributo como ngClass
, ngStyle
e ngModel
devem ser colocadas entre aspas. Diretivas estruturais como *ngIf
, *ngFor
, *ngSwitchCase
e *ngSwitchDefault
também precisam ser colocadas entre aspas ou usadas com vírgulas. As variáveis de referência de modelo ( por exemplo #var
) não interferem na compilação do modelo Pug e, portanto, não precisam de aspas ou vírgulas. As expressões de modelo entre {{ }}
permanecem inalteradas.
Desvantagens e desvantagens de usar Pug em modelos angulares
Embora o Pug seja conveniente e melhore os fluxos de trabalho, há algumas desvantagens em usá-lo e algumas compensações que precisam ser consideradas ao usar ng-cli-pug-loader
.
Arquivos não podem ser incluídos em modelos usando include
a menos que terminem em .partial.pug
ou .include.pug
ou sejam chamados mixins.pug
. Além disso, a herança de modelo não funciona com ng-cli-pug-loader
e, como resultado, usar blocos, prefixar e anexar código Pug não é possível, apesar de ser um recurso útil do Pug.
Os arquivos Pug devem ser criados manualmente, pois o Angular CLI gera apenas componentes com modelos HTML. Você precisará excluir o arquivo HTML gerado e criar um arquivo Pug ou apenas alterar a extensão do arquivo HTML e, em seguida, alterar o templateUrl
no decorador do componente. Embora isso possa ser automatizado usando um script, um esquema ou um Task Runner, você precisa implementar a solução.
Em projetos Angular pré-existentes maiores, mudar de templates HTML para Pug envolve muito trabalho e complexidade em alguns casos. Fazer a troca levará a muito código de quebra que precisa ser corrigido arquivo por arquivo ou automaticamente usando uma ferramenta personalizada. Bindings e algumas diretivas Angular em elementos precisam ser citados ou separados por vírgulas.
Os desenvolvedores não familiarizados com o Pug precisam aprender a sintaxe antes de incorporá-lo a um projeto. Pug não é apenas HTML sem colchetes e tags de fechamento e envolve uma curva de aprendizado.
Ao escrever o Pug e usar seus recursos em templates Angular ng-cli-pug-loader
não dá aos templates Pug acesso às propriedades do componente. Como resultado, essas propriedades não podem ser usadas como variáveis, em condicionais, em iteradores e em código embutido. Diretivas angulares e expressões de modelo também não têm acesso a variáveis Pug. Por exemplo, com variáveis Pug:
//- app.component.pug - var shoppingList = ['Eggs', 'Milk', 'Flour'] //- will work ul each item in shoppingList li= item //- will not work because shoppingList is a Pug variable ul li(*ngFor="let item of shoppingList") {{item}}
Aqui está um exemplo com uma propriedade de um componente:
//- src/app/app.component.ts export class AppComponent{ shoppingList = ['Eggs', 'Milk', 'Flour']; }
//- app.component.pug //- will not work because shoppingList is a component property and not a Pug variable ul each item in shoppingList li= item //- will work because shoppingList is a property of the component ul li(*ngFor="let item of shoppingList") {{item}}
Por último, index.html
não pode ser um template Pug. ng-cli-pug-loader
não suporta isso.
Conclusão
O Pug pode ser um recurso incrível para usar em aplicativos Angular, mas requer algum investimento para aprender e integrar em um projeto novo ou pré-existente. Se você estiver pronto para o desafio, você pode dar uma olhada na documentação do Pug para aprender mais sobre sua sintaxe e adicioná-la aos seus projetos. Embora ng-cli-pug-loader
seja uma ótima ferramenta, pode faltar em algumas áreas. Para personalizar como o Pug funcionará em seu projeto, considere criar um esquema Angular que atenda aos requisitos do seu projeto.