DEV Community

Eduardo Henrique Gris
Eduardo Henrique Gris

Posted on

Reducing manual work in React with Hygen

Introduction

When creating new components and modules in a React app, a project pattern is usually followed, of folder structure and file types. Based on the creation of a new component, one can proceed in the following ways: by duplicating folders and files from another component in the app, renaming file names, updating imports, and replacing code to match the definitions of the new component, or by creating folders and files manually. But how could the efficiency of this process of creating a new component be improved to be less manual?

Hygen

Hygen is a automatic code generation library, that based on templates definitions allows the generation of files and specifies the location in the application where these files will be created.

Setup

To add Hygen to the application, it's necessary to run the following command:

yarn add --dev hygen

To start Hygen in the project:

npx hygen init self

It will generate a _templates folder where two folders will be created with some initial files, that will allow Hygen use. In _templates folder, we will define the templates for files generation.

Image description

Next, it will be necessary to create a code generator from the following command, where instead of generator_name, it is defined the name that represents it (for example, component can be put for a component generator):

npx hygen generator new generator_name

This command will generate a folder structure _templates/generator_name/new, with an initial example template. Inside generator_name/new, all the templates that will be used, when running the generator in the terminal, will be defined. The initial example template (hello.ejs.t) comes with the following code:

---
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)

Enter fullscreen mode Exit fullscreen mode

Where to: defines the location where the new file will be created, and below it is the code that will be generated. All template files follow the pattern template_name.ejs.t.

To run the generator and create new files from the templates defined inside it, I suggest creating a script in package.json for execute hygen generator_name new. Here's an example starting from a generator with generator_name equal to component:

"scripts": {
  (...),
  "create-component": "hygen component new"
},
Enter fullscreen mode Exit fullscreen mode

For executing the generator:

yarn create-component

After executing this command, all templates inside component/new will generate new files.

In addition to creating new files, Hygen allows code injection into existing files. For this purpose, to: have to be set to the path of an existing file inside the app. Inside the template, needs to define inject: true, and to specify the injection point, one way is to define the line to be included by adding at_line:, following the structure below:

---
inject: true
to: existing_file_path
at_line: 0
---
Enter fullscreen mode Exit fullscreen mode

It's also possible to pass a dynamic value inside the templates by using <%=name%>, both in the definition of the code to be generated and in the definition of the file location. Below is an example of usage in the definition of the file location:

---
to: src/components/<%=name%>.js
---
Enter fullscreen mode Exit fullscreen mode

Using the example of a generator named component, when executing the command yarn create-component Input, the <%=name%> in the template above will be replaced by Input, and the file from this template will be generated in src/components/Input.js.

Execution example

Now I will present an example of executing Hygen to generate a new component. The idea is to demonstrate the process of creating files and injecting code into an existing file. Let's start with an app that has the following structure:

Image description

In src/components/Tag/Tag.js, the component is defined:

import React from "react";

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

export default Tag;
Enter fullscreen mode Exit fullscreen mode

In src/components/Tag/Tag.test.js, the tests:

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

import Tag from "./Tag";

describe("<Tag />", () => {
  (...)
});
Enter fullscreen mode Exit fullscreen mode

In src/components/Tag/index.js, the export inside the component folder:

export { default } from "./Tag";
Enter fullscreen mode Exit fullscreen mode

In src/components/index.js, the export inside the components folder:

export { default as Tag } from "./Tag";
Enter fullscreen mode Exit fullscreen mode

The first step is to create the code generator, that, as it is for component creation, I'll call component. Executing in the terminal:

npx hygen generator new component

This way, the folder structure _templates/component/new will be created with an example file.

Image description

As the file hello.ejs.t won't be used, it will be removed, and inside the new folder, the templates will be added. For the component creation, the template component.ejs.t will be created:

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

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

);

export default <%=name%>;

Enter fullscreen mode Exit fullscreen mode

For the tests, the 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%> />", () => {

});

Enter fullscreen mode Exit fullscreen mode

For the export inside the component folder, the template index.ejs.t:

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

Enter fullscreen mode Exit fullscreen mode

For the export inside the components folder, since the file already exists and has the export of the Tag component inside it, the code injection will be done using the template componentsIndex.ejs.t:

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

The <%=name%> will be the name of the component to be created, which will be defined when running the command to use the generator component. The templates will be defined as follows:

Image description

To execute the component generator, it will be added to package.json:

"scripts": {
  "create-component": "hygen component new"
},
Enter fullscreen mode Exit fullscreen mode

In this example, a button component called Button will be created. Therefore, when running the generator command, it will be necessary to add Button at the end, to all templates replace <%=name%> with Button:

yarn create-component Button

Image description

Showing in the terminal the three generated files and the existing file that had code added to it.

The folder structure, files, and code will be as defined in the templates.

Image description

Conclusion

Finally, the idea of this article is to demonstrate a way to reduce manual work in React development by automating part of the process. I provided an example related to creating components to illustrate how it works, but I have also encountered the use of Hygen for generating modules, which share the same folder structure, file types, Babel configuration, TypeScript setup, among others, speeding up the process of creating them using the library.

Top comments (0)