Reduzindo trabalho manual em React com Hygen
Tags: react, hygen, webdev, tutorial
Published: 2024-02-26 17:41:35

## Introdução

Na criação de novos componentes e módulos dentro de uma app React, normalmente se segue um padrão de projeto, de estrutura de pastas e tipos de arquivos. Partindo da criação de um novo componente, pode-se proceder por exemplo das seguintes formas: duplicar as pastas e arquivos de outro componente presente na app, renomeando os nomes dos arquivos, atualizando imports e substituindo código para corresponder as definições do novo componente ou criar as pastas e arquivos na mão. Mas como seria possível melhorar a eficiência desse processo de criação de um novo componente para ser menos manual? 

## Hygen

Hygen é uma lib de geração automática de código, a qual a partir de definição de templates permite a geração de arquivos e definir o local dentro da aplicação que esses arquivos serão criados.

## Setup

Para adicionar o Hygen na aplicação é necessário rodar o seguinte comando:

`yarn add --dev hygen`

Para iniciar o Hygen no projeto:

`npx hygen init self`

Ele vai gerar uma pasta `_templates` onde estarão duas pastas com alguns arquivos iniciais para uso do Hygen. Nessa pasta `_templates` será onde definiremos os templates para geração de arquivos.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3b8qifdtipjevbiu8lq0.png)

A seguir será necessário criar um gerador de código a partir do seguinte comando, onde no lugar de `nome_do_gerador` é colocado o nome que representa ele (por exemplo pode ser colocado `component` para um gerador de componentes):

`npx hygen generator new nome_do_gerador`

Esse comando vai gerar uma estrutura de pastas `_templates/nome_do_gerador/new`, com um template inicial de exemplo. Dentro de `nome_do_gerador/new`, será definido todos os templates que serão usados ao executar o gerador no terminal. O template inicial (hello.ejs.t) de exemplo vem com o seguinte código:

~~~
---
to: app/hello.js
---
const hello = ```
Hello!
This is your first hygen template.

Learn what it can do here:

https://github.com/jondot/hygen
```

console.log(hello)

~~~

Onde `to:` define o local que o novo arquivo será criado e abaixo dele está o código que vai ser gerado. Todos os arquivos de template seguem o padrão `nome_do_template.ejs.t`.
Para rodar o gerador e criar novos arquivos a partir dos templates definidos dentro dele, sugiro criar em `package.json` um script para execução de `hygen nome_do_gerador new`, segue um exemplo partindo de um gerador com `nome_do_gerador` igual `component`:

```
"scripts": {
  (...),
  "create-component": "hygen component new"
},
```

Para execução do gerador seria executar:

`yarn create-component`

Após executar esse comando, todos os templates dentro de `component/new` irão gerar novos arquivos.

Além de criação de novos arquivos o Hygen permite a injeção de código dentro de arquivos já existentes, para isso o `to:` tem que estar definido com o caminho de um arquivo já existente dentro da app, dentro do template tem que definir `inject: true` e para especificar o lugar para injeção uma das formas é definir a linha a ser incluída a adição de código `at_line:`, seguindo a estrutura abaixo:

```
---
inject: true
to: caminho_de_arquivo_existente
at_line: 0
---
```

Também é possível passar um valor dinâmico dentro dos templates colocando `<%=name%>`, tanto na definição do código a ser gerado quanto na definição do lugar do arquivo. Segue um exemplo abaixo de uso na definição do lugar do arquivo:

```
---
to: src/components/<%=name%>.js
---
```

Partindo do exemplo de um gerador com nome `component`, ao executar o comando `yarn create-component Input`, o `<%=name%>` do template acima vai ser substituído por `Input` e o arquivo desse template será gerado em `src/components/Input.js`.

## Exemplo de execução

Agora vou apresentar um exemplo de execução do Hygen para gerar um novo componente, a ideia é mostrar o funcionamento de criação de arquivos e injeção de código em arquivo existente. Vamos partir de uma app que tem a seguinte estrutura:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jrv8w4z0aueurut362u9.png)

Onde em `src/components/Tag/Tag.js` tem-se a definição do componente:

```
import React from "react";

const Tag = ({(...)}) => (
  <div>
    (...)
  </div>
);

export default Tag;
```

Em `src/components/Tag/Tag.test.js` os testes:

```
import React from "react";
import "@testing-library/jest-dom";
import { render, screen } from "@testing-library/react";

import Tag from "./Tag";

describe("<Tag />", () => {
  (...)
});
```

Em `src/components/Tag/index.js` o export dentro da pasta do componente:

```
export { default } from "./Tag";
```

Em `src/components/index.js` o export dentro da pasta `components`:

```
export { default as Tag } from "./Tag";
```

O primeiro passo é criar o gerador de código, o qual por ser de criação de componente vou chamar de `component`. Executando no terminal:

`npx hygen generator new component`

Dessa forma será criada a estrutura de pastas `_templates/component/new` e um arquivo de exemplo:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/loduw0v6abwb9xv798aq.png)

Como o arquivo `hello.ejs.t` não será utilizado, ele será removido e dentro da pasta `new` serão adicionados os templates.
Para a criação do componente, será criado o template `component.ejs.t`:

```
---
to: src/components/<%=name%>/<%=name%>.js
---
import React from "react";

const <%=name%> = ({}) => (

);

export default <%=name%>;

```

Para os testes o template `test.ejs.t`:

```
---
to: src/components/<%=name%>/<%=name%>.test.js
---
import React from "react";
import "@testing-library/jest-dom";
import { render, screen } from "@testing-library/react";

import <%=name%> from "./<%=name%>";

describe("<<%=name%> />", () => {

});

```

Para o export dentro da pasta do componente o template `index.ejs.t`:

```
---
to: src/components/<%=name%>/index.js
---
export { default } from "./<%=name%>";

```

Para o export dentro da pasta de componentes, uma vez que o arquivo já existe e tem o export do componente Tag dentro dele, será feito o inject de código com o template `componentsIndex.ejs.t`:

```
---
inject: true
to: src/components/index.js
at_line: 0
---
export { default as <%=name%> } from "./<%=name%>";
```

O `<%=name%>` vai ser o nome do componente a ser criado, que será definido quando rodar o comando para usar o gerador `component`.
Vai ficar da seguinte forma os templates definidos:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7hzbo0foit15bqmff6mp.png)

Para executar o gerador de componentes, vai ser adicionado em `package.json`:

```
"scripts": {
  "create-component": "hygen component new"
},
```

Nesse exemplo vai ser criado um componente de botão chamado de `Button`, para isso ao executar o comando para rodar o gerador será necessário adicionar `Button` no final, para que todos os templates substituam o `<%=name%>` por `Button`:

`yarn create-component Button`

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dkxu7c7q8ygectdx4exl.gif)

Mostrando no terminal os três arquivos gerados e o arquivo existente que teve código adicionado dentro dele.

Ficando a estrutura de pastas, arquivos e código da forma definida nos templates.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6zdzprk72lzzpu4mhfyc.png)

## Conclusão

Por fim, a ideia desse artigo é mostrar uma forma de reduzir trabalho manual no desenvolvimento em React, automatizando parte do processo. Passei um exemplo referente a criação de componentes para ilustrar o funcionamento, mas já me deparei com o uso do Hygen para geração de módulos, que compartilham a mesma estrutura de pastas, tipos de arquivos, configuração de Babel, typescript, dentre outras, acelerando o processo de criação deles utilizando a lib.