Experts in Angular

Angular CLIParte 4: Schematics para Bibliotecas no Angular
Executando o Schematic da sua Biblioteca: Dando Vida à sua Criação

Parte 4: Schematics para Bibliotecas no Angular

Executando o Schematic da sua Biblioteca: Dando Vida à sua Criação

Após construir sua biblioteca e seus Schematics, é hora de colocá-los em ação e ver como eles se integram ao seu projeto Angular. Nesta etapa final, vamos explorar como instalar a coleção de Schematics, vincular a biblioteca ao seu projeto e executar o Schematic de geração que você criou anteriormente.

Antes vamos ao resumos de como chegamos até aqui:

Resumo das Três Partes da Série de Artigos sobre Schematics em Angular

Ferramentas de Desenvolvimento: Angular CLI e Schematics para Bibliotecas

Ao criar uma biblioteca Angular, é possível integrá-la ao Angular CLI através de schematics. Com isso, usuários podem utilizar ng add para instalar a versão inicial da sua biblioteca, ng generate para criar artefatos definidos na sua biblioteca, e ng update para ajustar o projeto para uma nova versão que introduz alterações significativas. Todas as três categorias de schematics podem ser incluídas em uma coleção que você empacota com sua biblioteca.

Criando uma Coleção de Schematics

Iniciando uma Coleção

Para começar uma coleção, crie os arquivos necessários no diretório raiz da sua biblioteca:

  1. Crie a pasta schematics: Onde os schematics serão armazenados.
  2. Crie a pasta ng-add: Para armazenar seu primeiro schematic.
  3. Arquivo collection.json: Define o esquema inicial para a coleção.

Exemplo de collection.json:

{
  "$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json",
  "schematics": {
    "ng-add": {
      "description": "Add my library to the project.",
      "factory": "./ng-add/index#ngAdd",
      "schema": "./ng-add/schema.json"
    }
  }
}

Prover Suporte à Instalação

Através de um schematic para o comando ng add, você pode aprimorar o processo de instalação inicial para seus usuários:

  1. Arquivo index.ts: Crie a função de fábrica do schematic.

Exemplo de index.ts:

import {Rule} from '@angular-devkit/schematics';
import {addRootImport} from '@schematics/angular/utility';
import {Schema} from './schema';

export function ngAdd(options: Schema): Rule {
  return addRootImport(
    options.project,
    ({code, external}) => code`${external('MyLibModule', 'my-lib')}`,
  );
}

Esta função adiciona MyLibModule ao projeto do usuário, assegurando que as declarações de importação sejam geradas corretamente.

Defina o Tipo de Dependência

Configure como a biblioteca deve ser adicionada ao package.json do projeto, utilizando a opção save do ng-add.

Exemplo de configuração no package.json:

"ng-add": {
  "save": "devDependencies"
}

Construindo seus Schematics

Para empacotar seus schematics com a biblioteca, configure a biblioteca para construí-los separadamente e adicioná-los ao pacote final.

Configuração do TypeScript

Adicione um arquivo tsconfig.schematics.json próximo ao arquivo tsconfig.lib.json.

Exemplo de tsconfig.schematics.json:

{
  "compilerOptions": {
    "baseUrl": ".",
    "lib": ["es2018", "dom"],
    "declaration": true,
    "module": "commonjs",
    "moduleResolution": "node",
    "noEmitOnError": true,
    "noFallthroughCasesInSwitch": true,
    "noImplicitAny": true,
    "noImplicitThis": true,
    "noUnusedParameters": true,
    "noUnusedLocals": true,
    "rootDir": "schematics",
    "outDir": "../../dist/my-lib/schematics",
    "skipDefaultLibCheck": true,
    "skipLibCheck": true,
    "sourceMap": true,
    "strictNullChecks": true,
    "target": "es6",
    "types": ["jasmine", "node"]
  },
  "include": ["schematics/**/*"],
  "exclude": ["schematics/*/files/**/*"]
}

Scripts de Construção

Adicione scripts no arquivo package.json da sua biblioteca para compilar os schematics.

Exemplo de scripts de construção no package.json:

"scripts": {
  "build": "tsc -p tsconfig.schematics.json",
  "postbuild": "copyfiles schematics/*/schema.json schematics/*/files/** schematics/collection.json ../../dist/my-lib/"
}

Prover Suporte à Geração

Permita que usuários usem o comando ng generate para criar um artefato definido na sua biblioteca, como um serviço.

Configure o Novo Schematic

Adicione um schematic nomeado na coleção:

  1. Edite o collection.json: Para incluir o novo schematic.

Exemplo de atualização no collection.json:

{
  "$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json",
  "schematics": {
    "ng-add": {
      "description": "Add my library to the project.",
      "factory": "./ng-add/index#ngAdd",
      "schema": "./ng-add/schema.json"
    },
    "my-service": {
      "description": "Generate a service in the project.",
      "factory": "./my-service/index#myService",
      "schema": "./my-service/schema.json"
    }
  }
}

Crie o Arquivo de Esquema

Defina as opções disponíveis para o schematic no arquivo schema.json.

Exemplo de schema.json:

{
  "$schema": "http://json-schema.org/schema",
  "$id": "SchematicsMyService",
  "title": "My Service Schema",
  "type": "object",
  "properties": {
    "name": {
      "description": "The name of the service.",
      "type": "string"
    },
    "path": {
      "type": "string",
      "format": "path",
      "description": "The path to create the service.",
      "visible": false
    },
    "project": {
      "type": "string",
      "description": "The name of the project.",
      "$default": {
        "$source": "projectName"
      }
    }
   },
  "required": ["name"]
}

Adicione Arquivos de Template

Para adicionar artefatos ao projeto, crie templates no diretório schematics/my-service/files.

Exemplo de template:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class <%= classify(name) %>Service {
  constructor(private http: HttpClient) { }
}

Função de Fábrica do Schematic

Defina a função principal que realiza modificações no projeto do usuário.

Exemplo de index.ts:

import {
  Rule,
  Tree,
  SchematicsException,
  apply,
  url,
  applyTemplates,
  move,
  chain,
  mergeWith,
} from '@angular-devkit/schematics';
import {strings, normalize, virtualFs, workspaces} from '@angular-devkit/core';
import {Schema as MyServiceSchema} from './schema';

function createHost(tree: Tree): workspaces.WorkspaceHost {
  return {
    async readFile(path: string): Promise<string> {
      const data = tree.read(path);
      if (!data) {
        throw new SchematicsException('File not found.');
      }
      return virtualFs.fileBufferToString(data);
    },
    async writeFile(path: string, data: string): Promise<void> {
      return tree.overwrite(path, data);
    },
    async isDirectory(path: string): Promise<boolean> {
      return !tree.exists(path) && tree.getDir(path).subfiles.length > 0;
    },
    async isFile(path: string): Promise<boolean> {
      return tree.exists(path);
    },
  };
}

export function myService(options: MyServiceSchema): Rule {
  return async (tree: Tree) => {
    const host = createHost(tree);
    const {workspace} = await workspaces.readWorkspace('/', host);
    const project = options.project != null ? workspace.projects.get(options.project) : null;

    if (!project) {
      throw new SchematicsException(`Invalid project name: ${options.project}`);
    }

    const projectType = project.extensions.projectType === 'application' ? 'app' : 'lib';

    if (options.path === undefined) {
      options.path = `${project.sourceRoot}/${projectType}`;
    }

    const templateSource = apply(url('./files'), [
      applyTemplates({
        classify: strings.classify,
        dasherize: strings.dasherize,
        name: options.name,
      }),
      move(normalize(options.path as string)),
    ]);

    return chain([mergeWith(templateSource)]);
  };
}

Construindo sua Biblioteca e Schematics: Preparando a Nave para o Lançamento

Antes de executar o Schematic, você precisa construir sua biblioteca e seus Schematics para garantir que eles estejam atualizados e prontos para uso.

Construa sua biblioteca:

Na raiz do seu workspace, execute o comando ng build para sua biblioteca.

ng build my-lib

Este comando compila sua biblioteca e gera os arquivos na pasta dist/my-lib.

Construa seus Schematics

Navegue até o diretório da sua biblioteca e execute o script de build dos Schematics.

cd projects/my-lib
npm run build

Isso compilará os schematics, preparando-os para serem executados em qualquer projeto Angular.

Fazendo o Link da Biblioteca

Para testar seu schematic localmente, você precisa criar um link simbólico da sua biblioteca no diretório node_modules. Isso facilita a importação da biblioteca e a execução dos schematics:

Crie o link simbólico:No diretório raiz do seu workspace, execute o seguinte comando:

npm link dist/my-lib

Com este comando, o NPM cria um link simbólico para sua biblioteca no diretório node_modules, permitindo que ela seja utilizada como se estivesse publicada em um registro NPM.

Executando o Schematic

Agora que sua biblioteca está devidamente instalada, você pode executar o schematic utilizando o comando ng generate. Este comando aplica as transformações definidas no seu schematic, gerando novos artefatos no projeto:

Execute o comando de geração:No terminal, utilize o seguinte comando para gerar um novo serviço usando seu schematic:

ng generate my-lib:my-service --name my-data

Este comando invoca o schematic my-service de sua biblioteca my-lib, utilizando o nome my-data para o serviço a ser criado.

Verifique o resultado:

Após a execução do comando, você deve ver a seguinte saída no console, indicando que o serviço foi criado com sucesso:

CREATE src/app/my-data.service.ts (208 bytes)

O arquivo my-data.service.ts foi gerado no diretório src/app do seu projeto, mostrando que o schematic foi aplicado com êxito.

Conclusão da Série: Sua Nave Espacial Angular Está Pronta para a Jornada

Ao longo desta série de artigos, exploramos o mundo dos Schematics do Angular CLI, desde os conceitos básicos até a criação de Schematics personalizados para bibliotecas. Com essas ferramentas poderosas em mãos, você pode automatizar tarefas, gerar código de alta qualidade e personalizar o Angular CLI para atender às suas necessidades.

Lembre-se, os Schematics são seus aliados na jornada de desenvolvimento Angular. Com criatividade e conhecimento, você pode construir Schematics que transformam seus projetos e elevam a experiência de desenvolvimento a um novo patamar.

Agora, sua nave espacial Angular está pronta para decolar. Explore o universo, crie aplicações incríveis e compartilhe seu conhecimento com a comunidade!