Creating React Components with Hygen

Have you ever used Hygen , an automatic code generator? If not already, perhaps our translation will open up a useful new tool for you.








When developing in React, creating components manually is rather difficult if the number of files that make up a component grows (for example, a Storybook file, a file with tests, a CSS module).



Imagine one component structured like this:







Hygen is a Node.js-based code generator that automates common code routines with an interactive command.



In this article, you will learn how to efficiently create React components using Hygen.



The final codebase on GitHub is available at this link .



Overview



To test Hygen, we'll set up a React app by following these steps:



  1. Create React App
  2. Configure Hygen
  3. Create template files
  4. Create config file
  5. Add scripts to package.json .




1. Create a React application



To speed things up, we'll use create-react-app to create a React app:



npx create-react-app hygen-app --template typescript
      
      





Once installed, you can start the dev server by running this command:



yarn start
      
      





After that we will see the welcome page:







2. Configure Hygen

Next, install and configure Hygen.



To install Hygen:



yarn add -D hygen
      
      





Next step: we will create template files for creating React components.



Default Hygen selects the folder _templates at any level of the project folder to download the template files.



In this article, we will add its own folder for it. To do this, add .hygen.js to your project root:



module.exports = {
  templates: `${__dirname}/.hygen`,
}
      
      





This will replace the default path ( _templates ) with the .hygen folder .



And add new / components to the .hygen folder :



.hygen

└── new

    └── component









3. Create template files



Now that we have configured Hygen, we will create the following template files:



  • index.ts
  • React component
  • Test file
  • Storybook File
  • CSS module




index.ts



First, we'll create a template for index.ts that exports all of the folder's dependencies.



Add index.tsx.ejs.t to .hygen / new / component :



---
to: <%= absPath %>/index.tsx
---
export * from './<%= component_name %>';
      
      





Hygen uses Frontmatter as its metadata template and EJS engine for the body.



In the header, we put a to property that is used for the output path for the files.



You can check all properties in the documentation .







<% =% AbsPath> - this tag EJS , which displays the value in the template.



In this case, if we assign src / components / atom / Button to the absPath variable , the path is src / components / atom / Button / index.tsx .



In order to pass the variable, we need to create an index.js for the setup, which we will look at. Later, create a section in the config file.



React components



Next, we'll create a template for the React component.



Add component.tsx.ejs.t to .hygen / new / component :



---
to: <%= absPath %>/<%= component_name %>.tsx
---
import React from 'react';
import styles from './style.module.css';

type Props = {};

export const <%= component_name %>: React.FC<Props> = (props) => {
  return <div className={styles.container} data-testid="test" />;
};
      
      







Test file



Next, we will create a template for the Test file.



Add test.tsx.ejs.t to .hygen / new / component :



---
to: <%= absPath %>/__tests__/<%= component_name %>.test.tsx
---
import React from 'react';
import { render, screen } from '@testing-library/react';
import { <%= component_name %> } from '../';

test('renders component successfully', () => {
  render(<<%= component_name %>  />);
  const element = screen.getByTestId(/test/i);
  expect(element).toBeInTheDocument();
});
      
      







Storybook File



In this step, we will create a template for the Storybook file.



Add stories.tsx.ejs.t to .hygen / new / component :



---
to: <%= absPath %>/<%= component_name %>.stories.tsx
---
import React from 'react';
import { <%= component_name %> } from './';
import { Story, Meta } from '@storybook/react/types-6-0';

type Props = React.ComponentProps<typeof <%= component_name %>>

const csf: Meta = {
  title: '<%= category %>/<%= component_name %>',
}

const Template: Story<Props> = (args) => <<%= component_name %> {...args} />;

export const c1 = Template.bind({});
c1.storyName = 'default'

export default csf
      
      







CSS module



Let's create a template for the CSS module.



Add style.module.css.ejs.t to .hygen / new / component :



---
to: <%= absPath %>/style.module.css
---
.container {}
      
      







4. Create config file



Now that we have configured all the template files, we will create a configuration file for Hygen.



Let's add index.js to .hygen / new / component :



module.exports = {
  prompt: ({ inquirer }) => {
    const questions = [
      {
        type: 'select',
        name: 'category',
        message: 'Which Atomic design level?',
        choices: ['atoms', 'molecules', 'organisms', 'templates', 'pages']
      },
      {
        type: 'input',
        name: 'component_name',
        message: 'What is the component name?'
      },
      {
        type: 'input',
        name: 'dir',
        message: 'Where is the directory(Optional)',
      },
    ]
    return inquirer
      .prompt(questions)
      .then(answers => {
        const { category, component_name, dir } = answers
        const path = `${category}/${ dir ? `${dir}/` : `` }${component_name}`
        const absPath = `src/components/${path}`
        return { ...answers, path, absPath, category }
      })
  }
}
      
      





This is the configuration file for an interactive prompt that asks you a few questions when it starts up. You can customize whatever you want in this file.



prompt receives response data and returns it. As I wrote above, they will be used in the EJS template file.



In this case, answers , path , absPath and category are passed to EJS .



More detailed description on GitHub .



5. Add scripts to package.json



Now that we're ready to run Hygen, we'll add scripts to package.json :



"scripts": {
  "start": "react-scripts start",
  "build": "react-scripts build",
  "test": "react-scripts test",
  "eject": "react-scripts eject",

  "new:component": "hygen new component" // Add here
},
      
      





Hygen automatically checks the folder structure and displays it. In this case, we have to pass the new component according to the folder structure: Great, let's try it! Let's create a Button component :



.hygen

└── new

    └── component















yarn new:component
      
      





An interactive tip will appear that will help with solving your questions:







We have generated these files in the src / components folder :



├── components

│   └── atoms

│       └── Button

│           ├── Button.stories.tsx

│           ├── Button.tsx

│           ├── __tests__

│           │   └── Button.test.tsx

│           ├── index.tsx

│           └── style.module.css









Conclusion



That's all! We looked at how to automate React development tasks using Hygen. You can of course apply it to other projects as well using Vue.js or Angular.



Hygen is quite flexible, so you can customize hints and templates to suit your needs.



So the final codebase is available here . It also contains the Storybook setting.



Hope this article helps you find some inspiration. Good luck!



All Articles