Eduardo Henrique Gris
Posted on February 26, 2024
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.
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)
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"
},
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
---
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
---
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:
In src/components/Tag/Tag.js
, the component is defined:
import React from "react";
const Tag = ({(...)}) => (
<div>
(...)
</div>
);
export default Tag;
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 />", () => {
(...)
});
In src/components/Tag/index.js
, the export inside the component folder:
export { default } from "./Tag";
In src/components/index.js
, the export inside the components
folder:
export { default as Tag } from "./Tag";
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.
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%>;
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%> />", () => {
});
For the export inside the component folder, the template index.ejs.t
:
---
to: src/components/<%=name%>/index.js
---
export { default } from "./<%=name%>";
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%>";
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:
To execute the component generator, it will be added to package.json
:
"scripts": {
"create-component": "hygen component new"
},
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
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.
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.
Posted on February 26, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.