Angular Schematics — Criando Projetos Customizados

Gleison de Almeida Ribeiro
7 min readApr 8, 2022
Os Schematics do Angular nos dá uma maneira de criar ações personalizadas, semelhantes às fornecidas pela CLI Angular. Os Schematics são usados ​​por muitas bibliotecas Angular de forma a simplificar seu uso.

Introdução

É muito comum realizarmos a criação de projetos Angular seguindo algum tipo de estrutura padrão de pastas ou até mesmo com a utilização de alguns arquivos de base, uma forma de evitar repetir todo o processo em projetos novos e melhorar a produtividade é utilizando os Schematics do Angular.

O Angular Schematics foi introduzido pela equipe Angular em 2018 e fornece uma API para gerar e gerenciar arquivos em seu projeto Angular, além de fornecer todas as dependências necessárias. Pense nisso como uma ferramenta de templates.

Suponhamos que seja bem comum que você e/ou seu time realize a criação de projetos que seguem a estrutura abaixo.

Estrutura de exemplo a ser replicada com schematics (isso é só um exemplo)

Iremos realizar a criação de um schematics que estende do ng newpadrão do angular e irá criar exatamente essa estrutura.

Criando Uma Collection de Schematics

Primeiro, certifique-se de ter o Node 6.9 ou superior instalado. Em seguida, instale a CLI do Schematics de forma global.

npm install -g @angular-devkit/schematics-cli

Com Isso agora temos acessos a CLI do schematics , que você pode usar para criar uma nova collection em branco:

schematics blank mdn-schematics
collection gerada.
collection.json padrão gerada pelo schematics

Aqui temos a propriedade schematics do arquivo collection.json que armazena todas as schematics que podemos ter no projeto.

Note que temos uma propriedade que declara o nome da nossa schematics e na propriedade factory indicamos o caminho para o arquivo onde está a schematic e qual método devemos executar deste arquivo indicado após o simbolo de #.

index.ts padrão gerado pelo schematics

As Partes de um Schematics

Após passar algum tempo construindo seu próprio Schematics, você perceberá que um Schematics é composto pelos seguintes arquivos.

  1. collection.json- Arquivo de definições de 1 ou mais Schematics.
  2. index.ts - Arquivo que contem o código de implementação da Schematic.
  3. schema.json - Arquivo que define os tipos e valores padrão das variáveis ​​usadas pelo schematic.
  4. schema.d.ts - Arquivo com as tipagens do Schema.
  5. files/- Arquivos que servirão como templates a serem replicados.

Tipos Básicos

  • O objeto Tree é a representação virtual estruturada de cada arquivo do workspace ao qual aplicamos o schematics. Em um Schematics você não executa nenhuma ação direta no sistema de arquivos.
    Em vez disso, você descreve quais modificações gostaria de aplicar a uma Tree, ao fazer modificações, você não altera a base, mas adiciona essas modificações à staging area, que posteriormente são aplicadas a base.
  • O objeto Rule é uma função que é invocada recebendo uma Tree e um SchematicContext. O objeto Rule geralmente é utilizado para fazer alterações em uma Tree e retornar essa Treealterada.
  • O objeto SchematicContext fornece acesso a funções utilitárias e metadados com os quais o schematic pode precisar trabalhar, incluindo uma API de logs para ajudar no processo de debug. Este objeto também define uma estratégia de mesclagem que determina como as alterações são mescladas da Treeatual na Treebase. Uma mudança pode ser aceita ou ignorada, ou lançar uma exceção.

Integrando ao ng-new

Para que seja possível que nossa schematics seja executada durante o ng new do usuário precisamos alterar a chave do nome da schematics para ng-new, vamos aproveitar e também alterar o nome do método a ser executado para main e acrescentar um log para realizarmos um teste de execução.

Alterado o nome da schematics para ng-new
Alterado o nome da função para main

Para realizar-mos o nosso primeiro teste devemos fazer o build do projeto com o comando npm run build

para evitar ficar executando este script a todo momento, acrescente mais 1 script no package.json, para rebuildar o projeto a medida que alterações forem feitas.

"watch": "tsc -p tsconfig.json --watch"

agora com o comando schematics .:ng-newda schematics CLI podemos testar a nossa schematics

Resultado da execução do schematics

Veja que foi executado o log com sucesso, sinal que nossa schematics já esta funcionando, apesar de não realizar nenhuma modificação ainda.

Recebendo Inputs do Usuário

Para que possamos receber e utilizar dados passados pelo o usuário via terminal, iremos criar um arquivo chamado schema.json dentro da pasta da nossa schematics, no nosso caso mdn-schematics.

Nesse arquivo podemos definir os tipos das variáveis a serem passadas na propriedade propertiese perguntas a serem exibidas para o usuário no terminal, utilizando as propriedades x-prompt .

Criação do arquivo schema.json

Nesse caso estamos definindo uma propriedade name do tipo string que é obrigatória ser passada pelo usuário.

O valor da propriedade x-prompt é a mensagem que o schematics usará para solicitar um valor ao usuário, se ele não fornecer um. Com a proriedade $default é possível definir um valor padrão. Nesse caso, o valor padrão será o primeiro argumento que o usuário passar na linha de comando.

Também é necessário acescentar a propriedade schema com o caminho para o schema no arquivo collection.json

Dessa forma, poderemos usar nosso schematics de três maneiras.

1 - Apenas chamando o schematics, sem passar nada. O schematics irá pedir um nome, exibindo a mensagem que definimos na propriedade x-prompt.

Executando o schematics sem passar parâmetro

2 - Chamando o schematic passando a flag name e seu valor.

Executando o schematics passando a flag — name

3 - Chamando o schematics passando apenas um valor como argumento.

Executando o schematics passando apenas o valor

Com isso também podemos criar um interface para representar a estrutura dos parâmetros passados para a nossa função main.

Criação da inteface SchemaOptions

Executando uma Schematic externa

Agora que ja sabemos como receber paramêtros do nosso usuário, não iremos querer reinventar a roda e realizar toda a criação de um projeto Angular do 0 novamente, para isso iremos reutilizar a schematics ng-newdo proprio Angular, e já definir algumas opções por padrão.

Para isso iremos criar um função chamada runNgNewSchematic que irá utilizar de uma função chamada externalSchematic do pacote @angular-devkit/schematics passando o name que recebemos como parâmetro e definindo outras opções por padrão.

Criação da função runNgNewSchematic

Também será necessário instalar o pacote @schematics/angulare informar no arquivo collection.json que iremos estender o schematics do angular.

Adicionado a propriedade “extends”: [“@schematics/angular”],

Agora ao executar a nossa schematics, o ng-newpadrão do angular também será chamado.

execução do ng-new através da nossa schematics

Explorando a Schematic API

A API do Schematics fornece muitas funções e objetos utilitários para manipular arquivos e pastas.

O objeto Tree tem um método create, mas apenas para criação de arquivos. Como transformar isso em nossa vantagem para criar uma pasta?

Você conhece o arquivo .gitkeep? Quando você cria um diretório vazio, o Git não o versiona. Ao adicionar este arquivo .gitkeep notificará o git para versioná-lo. Então, este é o truque: criar um .gitkeep é a chave para gerar uma pasta vazia!

Agora podemos criar uma função que ira manipular a Treee criar todas as pastas padrões necessárias do nosso projeto.

Criação das pastas vazias

Aqui estamos utilizando o método chain que faz a combinação de multiplas Rules em apenas 1.

Ao executar nossa schematics novamente veremos que as pastas agora foram criadas.

Criação das pastas de base

Mas e a pasta sass mostrada no ínicio com aqueles partial files?

Angular Schematic Template Files

Sim, você pode codar um schematics inteiro apenas no arquivo index.ts. No entanto, é mais útil e eficiente trabalhar com arquivos de modelo que podemos apenas injetar variáveis se necessário (que não será o nosso caso) ​​e cuspir código. Então, a primeira coisa que precisamos fazer é adicionar uma pasta files em src/mdn-schematics e colocar os arquivos de modelo lá.

adicionando pasta com arquivo de template

Agora iremos realizar a criação de mais uma função no index.ts que ira criar essa pasta com todos esses arquivos durante a execução do schematics.

Criação da função createSassFolder

Aqui estamos utilizando as função apply que é responsável por aplicar multiplas Rules (segundo parâmetro) a um Source (primeiro parâmetro) e retornar o mesmo transformado.

Com a função urlcriamos um objeto Sourcea partir do endereço de uma pasta, e no segundo parâmetro estamos utilizando a função move para aplicar uma Rule que move os templates para o nosso camimnho esperado.

Agora ao exercutarmos novamente a nossa schematics teremos a pasta sass criada com os arquivos de template.

Pasta sass criada com os arquivos de template

Publicando no NPM

Agora podemos realizar a publicação da nossa schematics no npmusando o comando npm publish

resultado do comando npm publish

E com isso temos a nossa schematic publicada no npm.

Para realizar a utilização da schematics é necessário instalar o pacote de forma global npm i -g mdn-schematics e executa-la junto com o comando do angular ng new -c=mdn-schematics .

Referências:

Espero que isso seja útil para você e até a próxima.

O projeto utilizado neste artigo pode ser encontrado neste repositório do GitHub.

E o schematics publicado pode ser acessado npm.

--

--

Gleison de Almeida Ribeiro

Frontend Software Developer Angular | Graduando em Sistemas de Informação.